Vokturz commited on
Commit
948b11c
·
1 Parent(s): b896b80

example working

Browse files
Files changed (7) hide show
  1. package.json +1 -0
  2. pnpm-lock.yaml +517 -0
  3. react.md +512 -0
  4. src/App.tsx +206 -17
  5. src/components/PipelineSelector.tsx +28 -0
  6. src/types.ts +22 -0
  7. src/worker.js +41 -0
package.json CHANGED
@@ -3,6 +3,7 @@
3
  "version": "0.1.0",
4
  "private": true,
5
  "dependencies": {
 
6
  "@testing-library/dom": "^10.4.0",
7
  "@testing-library/jest-dom": "^6.6.3",
8
  "@testing-library/react": "^16.3.0",
 
3
  "version": "0.1.0",
4
  "private": true,
5
  "dependencies": {
6
+ "@huggingface/transformers": "^3.6.1",
7
  "@testing-library/dom": "^10.4.0",
8
  "@testing-library/jest-dom": "^6.6.3",
9
  "@testing-library/react": "^16.3.0",
pnpm-lock.yaml CHANGED
@@ -8,6 +8,9 @@ importers:
8
 
9
  .:
10
  dependencies:
 
 
 
11
  '@testing-library/dom':
12
  specifier: ^10.4.0
13
  version: 10.4.0
@@ -880,6 +883,9 @@ packages:
880
  '@dabh/[email protected]':
881
  resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==}
882
 
 
 
 
883
  '@eslint-community/[email protected]':
884
  resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==}
885
  engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -898,6 +904,13 @@ packages:
898
  resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==}
899
  engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
900
 
 
 
 
 
 
 
 
901
  '@humanwhocodes/[email protected]':
902
  resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==}
903
  engines: {node: '>=10.10.0'}
@@ -911,10 +924,130 @@ packages:
911
  resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
912
  deprecated: Use @eslint/object-schema instead
913
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
914
  '@isaacs/[email protected]':
915
  resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
916
  engines: {node: '>=12'}
917
 
 
 
 
 
918
  '@istanbuljs/[email protected]':
919
  resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==}
920
  engines: {node: '>=8'}
@@ -1057,6 +1190,36 @@ packages:
1057
  webpack-plugin-serve:
1058
  optional: true
1059
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1060
  '@rollup/[email protected]':
1061
  resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
1062
  engines: {node: '>= 10.0.0'}
@@ -1770,6 +1933,10 @@ packages:
1770
1771
  resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
1772
 
 
 
 
 
1773
1774
  resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
1775
 
@@ -1874,6 +2041,10 @@ packages:
1874
  resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
1875
  engines: {node: '>= 8.10.0'}
1876
 
 
 
 
 
1877
1878
  resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
1879
  engines: {node: '>=6.0'}
@@ -1922,6 +2093,10 @@ packages:
1922
1923
  resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==}
1924
 
 
 
 
 
1925
1926
  resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==}
1927
 
@@ -2250,6 +2425,10 @@ packages:
2250
  resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
2251
  engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
2252
 
 
 
 
 
2253
2254
  resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
2255
  engines: {node: '>=8'}
@@ -2435,6 +2614,9 @@ packages:
2435
  resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
2436
  engines: {node: '>= 0.4'}
2437
 
 
 
 
2438
2439
  resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
2440
  engines: {node: '>=6'}
@@ -2720,6 +2902,9 @@ packages:
2720
  resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
2721
  engines: {node: ^10.12.0 || >=12.0.0}
2722
 
 
 
 
2723
2724
  resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
2725
 
@@ -2851,6 +3036,10 @@ packages:
2851
  resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
2852
  deprecated: Glob versions prior to v9 are no longer supported
2853
 
 
 
 
 
2854
2855
  resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==}
2856
  engines: {node: '>=6'}
@@ -2881,6 +3070,9 @@ packages:
2881
2882
  resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
2883
 
 
 
 
2884
2885
  resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
2886
  engines: {node: '>=10'}
@@ -3502,6 +3694,9 @@ packages:
3502
3503
  resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
3504
 
 
 
 
3505
3506
  resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
3507
  hasBin: true
@@ -3626,6 +3821,9 @@ packages:
3626
  resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==}
3627
  engines: {node: '>= 12.0.0'}
3628
 
 
 
 
3629
3630
  resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
3631
  hasBin: true
@@ -3657,6 +3855,10 @@ packages:
3657
3658
  resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
3659
 
 
 
 
 
3660
3661
  resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
3662
  engines: {node: '>= 0.4'}
@@ -3745,10 +3947,19 @@ packages:
3745
  resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
3746
  engines: {node: '>=16 || 14 >=14.17'}
3747
 
 
 
 
 
3748
3749
  resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
3750
  hasBin: true
3751
 
 
 
 
 
 
3752
3753
  resolution: {integrity: sha512-9A8/eor2DXwpv1+a4pZAAydqLFVrWoKoO1fzdzqLUhYVXAO1Kgd1FR2gFZi7YdHzF0s4W8cDNwCfKJQrvLqxDw==}
3754
  engines: {node: '>v0.4.10'}
@@ -3887,6 +4098,19 @@ packages:
3887
  resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
3888
  engines: {node: '>=6'}
3889
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3890
3891
  resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
3892
  engines: {node: '>=12'}
@@ -4014,6 +4238,9 @@ packages:
4014
  resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==}
4015
  engines: {node: '>=8'}
4016
 
 
 
 
4017
4018
  resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
4019
  engines: {node: '>= 0.4'}
@@ -4487,6 +4714,10 @@ packages:
4487
4488
  resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
4489
 
 
 
 
 
4490
4491
  resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
4492
  engines: {node: '>= 0.10'}
@@ -4703,6 +4934,10 @@ packages:
4703
  deprecated: Rimraf versions prior to v4 are no longer supported
4704
  hasBin: true
4705
 
 
 
 
 
4706
4707
  resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==}
4708
  deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser
@@ -4797,6 +5032,9 @@ packages:
4797
  resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==}
4798
  engines: {node: '>=10'}
4799
 
 
 
 
4800
4801
  resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
4802
  hasBin: true
@@ -4810,6 +5048,10 @@ packages:
4810
  resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==}
4811
  engines: {node: '>= 0.8.0'}
4812
 
 
 
 
 
4813
4814
  resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==}
4815
 
@@ -4842,6 +5084,10 @@ packages:
4842
4843
  resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
4844
 
 
 
 
 
4845
4846
  resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
4847
  engines: {node: '>=8'}
@@ -4936,6 +5182,9 @@ packages:
4936
4937
  resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
4938
 
 
 
 
4939
4940
  resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
4941
  deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
@@ -5116,6 +5365,10 @@ packages:
5116
  resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==}
5117
  engines: {node: '>=6'}
5118
 
 
 
 
 
5119
5120
  resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==}
5121
  engines: {node: '>=8'}
@@ -5235,6 +5488,10 @@ packages:
5235
  resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
5236
  engines: {node: '>=4'}
5237
 
 
 
 
 
5238
5239
  resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==}
5240
  engines: {node: '>=10'}
@@ -5614,6 +5871,10 @@ packages:
5614
5615
  resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
5616
 
 
 
 
 
5617
5618
  resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
5619
  engines: {node: '>= 6'}
@@ -6637,6 +6898,11 @@ snapshots:
6637
  enabled: 2.0.0
6638
  kuler: 2.0.0
6639
 
 
 
 
 
 
6640
  '@eslint-community/[email protected]([email protected])':
6641
  dependencies:
6642
  eslint: 8.57.1
@@ -6660,6 +6926,15 @@ snapshots:
6660
 
6661
  '@eslint/[email protected]': {}
6662
 
 
 
 
 
 
 
 
 
 
6663
  '@humanwhocodes/[email protected]':
6664
  dependencies:
6665
  '@humanwhocodes/object-schema': 2.0.3
@@ -6672,6 +6947,87 @@ snapshots:
6672
 
6673
  '@humanwhocodes/[email protected]': {}
6674
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6675
  '@isaacs/[email protected]':
6676
  dependencies:
6677
  string-width: 5.1.2
@@ -6681,6 +7037,10 @@ snapshots:
6681
  wrap-ansi: 8.1.0
6682
  wrap-ansi-cjs: [email protected]
6683
 
 
 
 
 
6684
  '@istanbuljs/[email protected]':
6685
  dependencies:
6686
  camelcase: 5.3.1
@@ -6923,6 +7283,29 @@ snapshots:
6923
  type-fest: 0.21.3
6924
  webpack-dev-server: 4.15.2([email protected])
6925
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6926
6927
  dependencies:
6928
  '@babel/core': 7.28.0
@@ -7828,6 +8211,8 @@ snapshots:
7828
 
7829
7830
 
 
 
7831
7832
  dependencies:
7833
  balanced-match: 1.0.2
@@ -7948,6 +8333,8 @@ snapshots:
7948
  optionalDependencies:
7949
  fsevents: 2.3.3
7950
 
 
 
7951
7952
 
7953
@@ -7996,6 +8383,11 @@ snapshots:
7996
  color-convert: 1.9.3
7997
  color-string: 1.9.1
7998
 
 
 
 
 
 
7999
8000
 
8001
@@ -8303,6 +8695,8 @@ snapshots:
8303
 
8304
8305
 
 
 
8306
8307
 
8308
@@ -8541,6 +8935,8 @@ snapshots:
8541
  is-date-object: 1.1.0
8542
  is-symbol: 1.1.1
8543
 
 
 
8544
8545
 
8546
@@ -8958,6 +9354,8 @@ snapshots:
8958
  keyv: 4.5.4
8959
  rimraf: 3.0.2
8960
 
 
 
8961
8962
 
8963
@@ -9101,6 +9499,15 @@ snapshots:
9101
  once: 1.4.0
9102
  path-is-absolute: 1.0.1
9103
 
 
 
 
 
 
 
 
 
 
9104
9105
  dependencies:
9106
  global-prefix: 3.0.0
@@ -9135,6 +9542,8 @@ snapshots:
9135
 
9136
9137
 
 
 
9138
9139
  dependencies:
9140
  duplexer: 0.1.2
@@ -10009,6 +10418,8 @@ snapshots:
10009
 
10010
10011
 
 
 
10012
10013
  dependencies:
10014
  minimist: 1.2.8
@@ -10128,6 +10539,8 @@ snapshots:
10128
  safe-stable-stringify: 2.5.0
10129
  triple-beam: 1.4.1
10130
 
 
 
10131
10132
  dependencies:
10133
  js-tokens: 4.0.0
@@ -10160,6 +10573,10 @@ snapshots:
10160
  dependencies:
10161
  tmpl: 1.0.5
10162
 
 
 
 
 
10163
10164
 
10165
@@ -10223,10 +10640,16 @@ snapshots:
10223
 
10224
10225
 
 
 
 
 
10226
10227
  dependencies:
10228
  minimist: 1.2.8
10229
 
 
 
10230
10231
 
10232
@@ -10361,6 +10784,25 @@ snapshots:
10361
  dependencies:
10362
  mimic-fn: 2.1.0
10363
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10364
10365
  dependencies:
10366
  define-lazy-prop: 2.0.0
@@ -10484,6 +10926,8 @@ snapshots:
10484
  dependencies:
10485
  find-up: 3.0.0
10486
 
 
 
10487
10488
 
10489
@@ -10958,6 +11402,21 @@ snapshots:
10958
  object-assign: 4.1.1
10959
  react-is: 16.13.1
10960
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10961
10962
  dependencies:
10963
  forwarded: 0.2.0
@@ -11275,6 +11734,15 @@ snapshots:
11275
  dependencies:
11276
  glob: 7.2.3
11277
 
 
 
 
 
 
 
 
 
 
11278
11279
  dependencies:
11280
  '@babel/code-frame': 7.27.1
@@ -11366,6 +11834,8 @@ snapshots:
11366
  '@types/node-forge': 1.3.12
11367
  node-forge: 1.3.1
11368
 
 
 
11369
11370
 
11371
@@ -11388,6 +11858,10 @@ snapshots:
11388
  transitivePeerDependencies:
11389
  - supports-color
11390
 
 
 
 
 
11391
11392
  dependencies:
11393
  randombytes: 2.1.0
@@ -11443,6 +11917,34 @@ snapshots:
11443
 
11444
11445
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11446
11447
  dependencies:
11448
  shebang-regex: 3.0.0
@@ -11548,6 +12050,8 @@ snapshots:
11548
 
11549
11550
 
 
 
11551
11552
 
11553
@@ -11781,6 +12285,15 @@ snapshots:
11781
 
11782
11783
 
 
 
 
 
 
 
 
 
 
11784
11785
 
11786
@@ -11890,6 +12403,8 @@ snapshots:
11890
 
11891
11892
 
 
 
11893
11894
 
11895
@@ -12400,6 +12915,8 @@ snapshots:
12400
 
12401
12402
 
 
 
12403
12404
 
12405
 
8
 
9
  .:
10
  dependencies:
11
+ '@huggingface/transformers':
12
+ specifier: ^3.6.1
13
+ version: 3.6.1
14
  '@testing-library/dom':
15
  specifier: ^10.4.0
16
  version: 10.4.0
 
883
  '@dabh/[email protected]':
884
  resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==}
885
 
886
+ '@emnapi/[email protected]':
887
+ resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==}
888
+
889
  '@eslint-community/[email protected]':
890
  resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==}
891
  engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
 
904
  resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==}
905
  engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
906
 
907
+ '@huggingface/[email protected]':
908
+ resolution: {integrity: sha512-3WXbMFaPkk03LRCM0z0sylmn8ddDm4ubjU7X+Hg4M2GOuMklwoGAFXp9V2keq7vltoB/c7McE5aHUVVddAewsw==}
909
+ engines: {node: '>=18'}
910
+
911
+ '@huggingface/[email protected]':
912
+ resolution: {integrity: sha512-cQVwrt/FawqGG/cDDT4+7Zdmw0HFignBirHsAUYI26HAj24oT2FxVyz2PgX6+qajutVLDekwhdChXxnZZB8XNg==}
913
+
914
  '@humanwhocodes/[email protected]':
915
  resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==}
916
  engines: {node: '>=10.10.0'}
 
924
  resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
925
  deprecated: Use @eslint/object-schema instead
926
 
927
+ '@img/[email protected]':
928
+ resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==}
929
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
930
+ cpu: [arm64]
931
+ os: [darwin]
932
+
933
+ '@img/[email protected]':
934
+ resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==}
935
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
936
+ cpu: [x64]
937
+ os: [darwin]
938
+
939
+ '@img/[email protected]':
940
+ resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==}
941
+ cpu: [arm64]
942
+ os: [darwin]
943
+
944
+ '@img/[email protected]':
945
+ resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==}
946
+ cpu: [x64]
947
+ os: [darwin]
948
+
949
+ '@img/[email protected]':
950
+ resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==}
951
+ cpu: [arm64]
952
+ os: [linux]
953
+
954
+ '@img/[email protected]':
955
+ resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==}
956
+ cpu: [arm]
957
+ os: [linux]
958
+
959
+ '@img/[email protected]':
960
+ resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==}
961
+ cpu: [ppc64]
962
+ os: [linux]
963
+
964
+ '@img/[email protected]':
965
+ resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==}
966
+ cpu: [s390x]
967
+ os: [linux]
968
+
969
+ '@img/[email protected]':
970
+ resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==}
971
+ cpu: [x64]
972
+ os: [linux]
973
+
974
+ '@img/[email protected]':
975
+ resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==}
976
+ cpu: [arm64]
977
+ os: [linux]
978
+
979
+ '@img/[email protected]':
980
+ resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==}
981
+ cpu: [x64]
982
+ os: [linux]
983
+
984
+ '@img/[email protected]':
985
+ resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==}
986
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
987
+ cpu: [arm64]
988
+ os: [linux]
989
+
990
+ '@img/[email protected]':
991
+ resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==}
992
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
993
+ cpu: [arm]
994
+ os: [linux]
995
+
996
+ '@img/[email protected]':
997
+ resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==}
998
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
999
+ cpu: [s390x]
1000
+ os: [linux]
1001
+
1002
+ '@img/[email protected]':
1003
+ resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==}
1004
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
1005
+ cpu: [x64]
1006
+ os: [linux]
1007
+
1008
+ '@img/[email protected]':
1009
+ resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==}
1010
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
1011
+ cpu: [arm64]
1012
+ os: [linux]
1013
+
1014
+ '@img/[email protected]':
1015
+ resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==}
1016
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
1017
+ cpu: [x64]
1018
+ os: [linux]
1019
+
1020
+ '@img/[email protected]':
1021
+ resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==}
1022
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
1023
+ cpu: [wasm32]
1024
+
1025
+ '@img/[email protected]':
1026
+ resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==}
1027
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
1028
+ cpu: [arm64]
1029
+ os: [win32]
1030
+
1031
+ '@img/[email protected]':
1032
+ resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==}
1033
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
1034
+ cpu: [ia32]
1035
+ os: [win32]
1036
+
1037
+ '@img/[email protected]':
1038
+ resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==}
1039
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
1040
+ cpu: [x64]
1041
+ os: [win32]
1042
+
1043
  '@isaacs/[email protected]':
1044
  resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
1045
  engines: {node: '>=12'}
1046
 
1047
+ '@isaacs/[email protected]':
1048
+ resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
1049
+ engines: {node: '>=18.0.0'}
1050
+
1051
  '@istanbuljs/[email protected]':
1052
  resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==}
1053
  engines: {node: '>=8'}
 
1190
  webpack-plugin-serve:
1191
  optional: true
1192
 
1193
+ '@protobufjs/[email protected]':
1194
+ resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
1195
+
1196
+ '@protobufjs/[email protected]':
1197
+ resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
1198
+
1199
+ '@protobufjs/[email protected]':
1200
+ resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==}
1201
+
1202
+ '@protobufjs/[email protected]':
1203
+ resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==}
1204
+
1205
+ '@protobufjs/[email protected]':
1206
+ resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==}
1207
+
1208
+ '@protobufjs/[email protected]':
1209
+ resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
1210
+
1211
+ '@protobufjs/[email protected]':
1212
+ resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==}
1213
+
1214
+ '@protobufjs/[email protected]':
1215
+ resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
1216
+
1217
+ '@protobufjs/[email protected]':
1218
+ resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
1219
+
1220
+ '@protobufjs/[email protected]':
1221
+ resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
1222
+
1223
  '@rollup/[email protected]':
1224
  resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
1225
  engines: {node: '>= 10.0.0'}
 
1933
1934
  resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
1935
 
1936
1937
+ resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==}
1938
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
1939
+
1940
1941
  resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
1942
 
 
2041
  resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
2042
  engines: {node: '>= 8.10.0'}
2043
 
2044
2045
+ resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
2046
+ engines: {node: '>=18'}
2047
+
2048
2049
  resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
2050
  engines: {node: '>=6.0'}
 
2093
2094
  resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==}
2095
 
2096
2097
+ resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
2098
+ engines: {node: '>=12.5.0'}
2099
+
2100
2101
  resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==}
2102
 
 
2425
  resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
2426
  engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
2427
 
2428
2429
+ resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==}
2430
+ engines: {node: '>=8'}
2431
+
2432
2433
  resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
2434
  engines: {node: '>=8'}
 
2614
  resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
2615
  engines: {node: '>= 0.4'}
2616
 
2617
2618
+ resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==}
2619
+
2620
2621
  resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
2622
  engines: {node: '>=6'}
 
2902
  resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
2903
  engines: {node: ^10.12.0 || >=12.0.0}
2904
 
2905
2906
+ resolution: {integrity: sha512-7JlN9ZvLDG1McO3kbX0k4v+SUAg48L1rIwEvN6ZQl/eCtgJz9UylTMzE9wrmYrcorgxm3CX/3T/w5VAub99UUw==}
2907
+
2908
2909
  resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
2910
 
 
3036
  resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
3037
  deprecated: Glob versions prior to v9 are no longer supported
3038
 
3039
3040
+ resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==}
3041
+ engines: {node: '>=10.0'}
3042
+
3043
3044
  resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==}
3045
  engines: {node: '>=6'}
 
3070
3071
  resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
3072
 
3073
3074
+ resolution: {integrity: sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==}
3075
+
3076
3077
  resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
3078
  engines: {node: '>=10'}
 
3694
3695
  resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
3696
 
3697
3698
+ resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
3699
+
3700
3701
  resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
3702
  hasBin: true
 
3821
  resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==}
3822
  engines: {node: '>= 12.0.0'}
3823
 
3824
3825
+ resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
3826
+
3827
3828
  resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
3829
  hasBin: true
 
3855
3856
  resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
3857
 
3858
3859
+ resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
3860
+ engines: {node: '>=10'}
3861
+
3862
3863
  resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
3864
  engines: {node: '>= 0.4'}
 
3947
  resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
3948
  engines: {node: '>=16 || 14 >=14.17'}
3949
 
3950
3951
+ resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==}
3952
+ engines: {node: '>= 18'}
3953
+
3954
3955
  resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
3956
  hasBin: true
3957
 
3958
3959
+ resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==}
3960
+ engines: {node: '>=10'}
3961
+ hasBin: true
3962
+
3963
3964
  resolution: {integrity: sha512-9A8/eor2DXwpv1+a4pZAAydqLFVrWoKoO1fzdzqLUhYVXAO1Kgd1FR2gFZi7YdHzF0s4W8cDNwCfKJQrvLqxDw==}
3965
  engines: {node: '>v0.4.10'}
 
4098
  resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
4099
  engines: {node: '>=6'}
4100
 
4101
4102
+ resolution: {integrity: sha512-Q632iLLrtCAVOTO65dh2+mNbQir/QNTVBG3h/QdZBpns7mZ0RYbLRBgGABPbpU9351AgYy7SJf1WaeVwMrBFPQ==}
4103
+
4104
4105
+ resolution: {integrity: sha512-vDJMkfCfb0b1A836rgHj+ORuZf4B4+cc2bASQtpeoJLueuFc5DuYwjIZUBrSvx/fO5IrLjLz+oTrB3pcGlhovQ==}
4106
+
4107
4108
+ resolution: {integrity: sha512-NeaCX6WW2L8cRCSqy3bInlo5ojjQqu2fD3D+9W5qb5irwxhEyWKXeH2vZ8W9r6VxaMPUan+4/7NDwZMtouZxEw==}
4109
+ os: [win32, darwin, linux]
4110
+
4111
4112
+ resolution: {integrity: sha512-0uS76OPgH0hWCPrFKlL8kYVV7ckM7t/36HfbgoFw6Nd0CZVVbQC4PkrR8mBX8LtNUFZO25IQBqV2Hx2ho3FlbQ==}
4113
+
4114
4115
  resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
4116
  engines: {node: '>=12'}
 
4238
  resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==}
4239
  engines: {node: '>=8'}
4240
 
4241
4242
+ resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==}
4243
+
4244
4245
  resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
4246
  engines: {node: '>= 0.4'}
 
4714
4715
  resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
4716
 
4717
4718
+ resolution: {integrity: sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==}
4719
+ engines: {node: '>=12.0.0'}
4720
+
4721
4722
  resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
4723
  engines: {node: '>= 0.10'}
 
4934
  deprecated: Rimraf versions prior to v4 are no longer supported
4935
  hasBin: true
4936
 
4937
4938
+ resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==}
4939
+ engines: {node: '>=8.0'}
4940
+
4941
4942
  resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==}
4943
  deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser
 
5032
  resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==}
5033
  engines: {node: '>=10'}
5034
 
5035
5036
+ resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==}
5037
+
5038
5039
  resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
5040
  hasBin: true
 
5048
  resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==}
5049
  engines: {node: '>= 0.8.0'}
5050
 
5051
5052
+ resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
5053
+ engines: {node: '>=10'}
5054
+
5055
5056
  resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==}
5057
 
 
5084
5085
  resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
5086
 
5087
5088
+ resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==}
5089
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
5090
+
5091
5092
  resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
5093
  engines: {node: '>=8'}
 
5182
5183
  resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
5184
 
5185
5186
+ resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==}
5187
+
5188
5189
  resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
5190
  deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
 
5365
  resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==}
5366
  engines: {node: '>=6'}
5367
 
5368
5369
+ resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==}
5370
+ engines: {node: '>=18'}
5371
+
5372
5373
  resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==}
5374
  engines: {node: '>=8'}
 
5488
  resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
5489
  engines: {node: '>=4'}
5490
 
5491
5492
+ resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
5493
+ engines: {node: '>=10'}
5494
+
5495
5496
  resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==}
5497
  engines: {node: '>=10'}
 
5871
5872
  resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
5873
 
5874
5875
+ resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
5876
+ engines: {node: '>=18'}
5877
+
5878
5879
  resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
5880
  engines: {node: '>= 6'}
 
6898
  enabled: 2.0.0
6899
  kuler: 2.0.0
6900
 
6901
+ '@emnapi/[email protected]':
6902
+ dependencies:
6903
+ tslib: 2.8.1
6904
+ optional: true
6905
+
6906
  '@eslint-community/[email protected]([email protected])':
6907
  dependencies:
6908
  eslint: 8.57.1
 
6926
 
6927
  '@eslint/[email protected]': {}
6928
 
6929
+ '@huggingface/[email protected]': {}
6930
+
6931
+ '@huggingface/[email protected]':
6932
+ dependencies:
6933
+ '@huggingface/jinja': 0.4.1
6934
+ onnxruntime-node: 1.21.0
6935
+ onnxruntime-web: 1.22.0-dev.20250409-89f8206ba4
6936
+ sharp: 0.34.2
6937
+
6938
  '@humanwhocodes/[email protected]':
6939
  dependencies:
6940
  '@humanwhocodes/object-schema': 2.0.3
 
6947
 
6948
  '@humanwhocodes/[email protected]': {}
6949
 
6950
+ '@img/[email protected]':
6951
+ optionalDependencies:
6952
+ '@img/sharp-libvips-darwin-arm64': 1.1.0
6953
+ optional: true
6954
+
6955
+ '@img/[email protected]':
6956
+ optionalDependencies:
6957
+ '@img/sharp-libvips-darwin-x64': 1.1.0
6958
+ optional: true
6959
+
6960
+ '@img/[email protected]':
6961
+ optional: true
6962
+
6963
+ '@img/[email protected]':
6964
+ optional: true
6965
+
6966
+ '@img/[email protected]':
6967
+ optional: true
6968
+
6969
+ '@img/[email protected]':
6970
+ optional: true
6971
+
6972
+ '@img/[email protected]':
6973
+ optional: true
6974
+
6975
+ '@img/[email protected]':
6976
+ optional: true
6977
+
6978
+ '@img/[email protected]':
6979
+ optional: true
6980
+
6981
+ '@img/[email protected]':
6982
+ optional: true
6983
+
6984
+ '@img/[email protected]':
6985
+ optional: true
6986
+
6987
+ '@img/[email protected]':
6988
+ optionalDependencies:
6989
+ '@img/sharp-libvips-linux-arm64': 1.1.0
6990
+ optional: true
6991
+
6992
+ '@img/[email protected]':
6993
+ optionalDependencies:
6994
+ '@img/sharp-libvips-linux-arm': 1.1.0
6995
+ optional: true
6996
+
6997
+ '@img/[email protected]':
6998
+ optionalDependencies:
6999
+ '@img/sharp-libvips-linux-s390x': 1.1.0
7000
+ optional: true
7001
+
7002
+ '@img/[email protected]':
7003
+ optionalDependencies:
7004
+ '@img/sharp-libvips-linux-x64': 1.1.0
7005
+ optional: true
7006
+
7007
+ '@img/[email protected]':
7008
+ optionalDependencies:
7009
+ '@img/sharp-libvips-linuxmusl-arm64': 1.1.0
7010
+ optional: true
7011
+
7012
+ '@img/[email protected]':
7013
+ optionalDependencies:
7014
+ '@img/sharp-libvips-linuxmusl-x64': 1.1.0
7015
+ optional: true
7016
+
7017
+ '@img/[email protected]':
7018
+ dependencies:
7019
+ '@emnapi/runtime': 1.4.3
7020
+ optional: true
7021
+
7022
+ '@img/[email protected]':
7023
+ optional: true
7024
+
7025
+ '@img/[email protected]':
7026
+ optional: true
7027
+
7028
+ '@img/[email protected]':
7029
+ optional: true
7030
+
7031
  '@isaacs/[email protected]':
7032
  dependencies:
7033
  string-width: 5.1.2
 
7037
  wrap-ansi: 8.1.0
7038
  wrap-ansi-cjs: [email protected]
7039
 
7040
+ '@isaacs/[email protected]':
7041
+ dependencies:
7042
+ minipass: 7.1.2
7043
+
7044
  '@istanbuljs/[email protected]':
7045
  dependencies:
7046
  camelcase: 5.3.1
 
7283
  type-fest: 0.21.3
7284
  webpack-dev-server: 4.15.2([email protected])
7285
 
7286
+ '@protobufjs/[email protected]': {}
7287
+
7288
+ '@protobufjs/[email protected]': {}
7289
+
7290
+ '@protobufjs/[email protected]': {}
7291
+
7292
+ '@protobufjs/[email protected]': {}
7293
+
7294
+ '@protobufjs/[email protected]':
7295
+ dependencies:
7296
+ '@protobufjs/aspromise': 1.1.2
7297
+ '@protobufjs/inquire': 1.1.0
7298
+
7299
+ '@protobufjs/[email protected]': {}
7300
+
7301
+ '@protobufjs/[email protected]': {}
7302
+
7303
+ '@protobufjs/[email protected]': {}
7304
+
7305
+ '@protobufjs/[email protected]': {}
7306
+
7307
+ '@protobufjs/[email protected]': {}
7308
+
7309
7310
  dependencies:
7311
  '@babel/core': 7.28.0
 
8211
 
8212
8213
 
8214
8215
+
8216
8217
  dependencies:
8218
  balanced-match: 1.0.2
 
8333
  optionalDependencies:
8334
  fsevents: 2.3.3
8335
 
8336
8337
+
8338
8339
 
8340
 
8383
  color-convert: 1.9.3
8384
  color-string: 1.9.1
8385
 
8386
8387
+ dependencies:
8388
+ color-convert: 2.0.1
8389
+ color-string: 1.9.1
8390
+
8391
8392
 
8393
 
8695
 
8696
8697
 
8698
8699
+
8700
8701
 
8702
 
8935
  is-date-object: 1.1.0
8936
  is-symbol: 1.1.1
8937
 
8938
8939
+
8940
8941
 
8942
 
9354
  keyv: 4.5.4
9355
  rimraf: 3.0.2
9356
 
9357
9358
+
9359
9360
 
9361
 
9499
  once: 1.4.0
9500
  path-is-absolute: 1.0.1
9501
 
9502
9503
+ dependencies:
9504
+ boolean: 3.2.0
9505
+ es6-error: 4.1.1
9506
+ matcher: 3.0.0
9507
+ roarr: 2.15.4
9508
+ semver: 7.7.2
9509
+ serialize-error: 7.0.1
9510
+
9511
9512
  dependencies:
9513
  global-prefix: 3.0.0
 
9542
 
9543
9544
 
9545
9546
+
9547
9548
  dependencies:
9549
  duplexer: 0.1.2
 
10418
 
10419
10420
 
10421
10422
+
10423
10424
  dependencies:
10425
  minimist: 1.2.8
 
10539
  safe-stable-stringify: 2.5.0
10540
  triple-beam: 1.4.1
10541
 
10542
10543
+
10544
10545
  dependencies:
10546
  js-tokens: 4.0.0
 
10573
  dependencies:
10574
  tmpl: 1.0.5
10575
 
10576
10577
+ dependencies:
10578
+ escape-string-regexp: 4.0.0
10579
+
10580
10581
 
10582
 
10640
 
10641
10642
 
10643
10644
+ dependencies:
10645
+ minipass: 7.1.2
10646
+
10647
10648
  dependencies:
10649
  minimist: 1.2.8
10650
 
10651
10652
+
10653
10654
 
10655
 
10784
  dependencies:
10785
  mimic-fn: 2.1.0
10786
 
10787
10788
+
10789
10790
+
10791
10792
+ dependencies:
10793
+ global-agent: 3.0.0
10794
+ onnxruntime-common: 1.21.0
10795
+ tar: 7.4.3
10796
+
10797
10798
+ dependencies:
10799
+ flatbuffers: 25.2.10
10800
+ guid-typescript: 1.0.9
10801
+ long: 5.3.2
10802
+ onnxruntime-common: 1.22.0-dev.20250409-89f8206ba4
10803
+ platform: 1.3.6
10804
+ protobufjs: 7.5.3
10805
+
10806
10807
  dependencies:
10808
  define-lazy-prop: 2.0.0
 
10926
  dependencies:
10927
  find-up: 3.0.0
10928
 
10929
10930
+
10931
10932
 
10933
 
11402
  object-assign: 4.1.1
11403
  react-is: 16.13.1
11404
 
11405
11406
+ dependencies:
11407
+ '@protobufjs/aspromise': 1.1.2
11408
+ '@protobufjs/base64': 1.1.2
11409
+ '@protobufjs/codegen': 2.0.4
11410
+ '@protobufjs/eventemitter': 1.1.0
11411
+ '@protobufjs/fetch': 1.1.0
11412
+ '@protobufjs/float': 1.0.2
11413
+ '@protobufjs/inquire': 1.1.0
11414
+ '@protobufjs/path': 1.1.2
11415
+ '@protobufjs/pool': 1.1.0
11416
+ '@protobufjs/utf8': 1.1.0
11417
+ '@types/node': 16.18.126
11418
+ long: 5.3.2
11419
+
11420
11421
  dependencies:
11422
  forwarded: 0.2.0
 
11734
  dependencies:
11735
  glob: 7.2.3
11736
 
11737
11738
+ dependencies:
11739
+ boolean: 3.2.0
11740
+ detect-node: 2.1.0
11741
+ globalthis: 1.0.4
11742
+ json-stringify-safe: 5.0.1
11743
+ semver-compare: 1.0.0
11744
+ sprintf-js: 1.1.3
11745
+
11746
11747
  dependencies:
11748
  '@babel/code-frame': 7.27.1
 
11834
  '@types/node-forge': 1.3.12
11835
  node-forge: 1.3.1
11836
 
11837
11838
+
11839
11840
 
11841
 
11858
  transitivePeerDependencies:
11859
  - supports-color
11860
 
11861
11862
+ dependencies:
11863
+ type-fest: 0.13.1
11864
+
11865
11866
  dependencies:
11867
  randombytes: 2.1.0
 
11917
 
11918
11919
 
11920
11921
+ dependencies:
11922
+ color: 4.2.3
11923
+ detect-libc: 2.0.4
11924
+ semver: 7.7.2
11925
+ optionalDependencies:
11926
+ '@img/sharp-darwin-arm64': 0.34.2
11927
+ '@img/sharp-darwin-x64': 0.34.2
11928
+ '@img/sharp-libvips-darwin-arm64': 1.1.0
11929
+ '@img/sharp-libvips-darwin-x64': 1.1.0
11930
+ '@img/sharp-libvips-linux-arm': 1.1.0
11931
+ '@img/sharp-libvips-linux-arm64': 1.1.0
11932
+ '@img/sharp-libvips-linux-ppc64': 1.1.0
11933
+ '@img/sharp-libvips-linux-s390x': 1.1.0
11934
+ '@img/sharp-libvips-linux-x64': 1.1.0
11935
+ '@img/sharp-libvips-linuxmusl-arm64': 1.1.0
11936
+ '@img/sharp-libvips-linuxmusl-x64': 1.1.0
11937
+ '@img/sharp-linux-arm': 0.34.2
11938
+ '@img/sharp-linux-arm64': 0.34.2
11939
+ '@img/sharp-linux-s390x': 0.34.2
11940
+ '@img/sharp-linux-x64': 0.34.2
11941
+ '@img/sharp-linuxmusl-arm64': 0.34.2
11942
+ '@img/sharp-linuxmusl-x64': 0.34.2
11943
+ '@img/sharp-wasm32': 0.34.2
11944
+ '@img/sharp-win32-arm64': 0.34.2
11945
+ '@img/sharp-win32-ia32': 0.34.2
11946
+ '@img/sharp-win32-x64': 0.34.2
11947
+
11948
11949
  dependencies:
11950
  shebang-regex: 3.0.0
 
12050
 
12051
12052
 
12053
12054
+
12055
12056
 
12057
 
12285
 
12286
12287
 
12288
12289
+ dependencies:
12290
+ '@isaacs/fs-minipass': 4.0.1
12291
+ chownr: 3.0.0
12292
+ minipass: 7.1.2
12293
+ minizlib: 3.0.2
12294
+ mkdirp: 3.0.1
12295
+ yallist: 5.0.0
12296
+
12297
12298
 
12299
 
12403
 
12404
12405
 
12406
12407
+
12408
12409
 
12410
 
12915
 
12916
12917
 
12918
12919
+
12920
12921
 
12922
react.md ADDED
@@ -0,0 +1,512 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # Building a React application
3
+
4
+ In this tutorial, we'll be building a simple React application that performs multilingual translation using Transformers.js! The final product will look something like this:
5
+
6
+ ![Demo](https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/react-translator-demo.gif)
7
+
8
+ Useful links:
9
+ - [Demo site](https://huggingface.co/spaces/Xenova/react-translator)
10
+ - [Source code](https://github.com/huggingface/transformers.js-examples/tree/main/react-translator)
11
+
12
+
13
+ ## Prerequisites
14
+
15
+ - [Node.js](https://nodejs.org/en/) version 18+
16
+ - [npm](https://www.npmjs.com/) version 9+
17
+
18
+
19
+ ## Step 1: Initialise the project
20
+
21
+ For this tutorial, we will use [Vite](https://vitejs.dev/) to initialise our project. Vite is a build tool that allows us to quickly set up a React application with minimal configuration. Run the following command in your terminal:
22
+
23
+ ```bash
24
+ npm create vite@latest react-translator -- --template react
25
+ ```
26
+
27
+ If prompted to install `create-vite`, type <kbd>y</kbd> and press <kbd>Enter</kbd>.
28
+
29
+ Next, enter the project directory and install the necessary development dependencies:
30
+
31
+ ```bash
32
+ cd react-translator
33
+ npm install
34
+ ```
35
+
36
+ To test that our application is working, we can run the following command:
37
+
38
+ ```bash
39
+ npm run dev
40
+ ```
41
+
42
+ Visiting the URL shown in the terminal (e.g., [http://localhost:5173/](http://localhost:5173/)) should show the default "React + Vite" landing page.
43
+ You can stop the development server by pressing <kbd>Ctrl</kbd> + <kbd>C</kbd> in the terminal.
44
+
45
+ ## Step 2: Install and configure Transformers.js
46
+
47
+ Now we get to the fun part: adding machine learning to our application! First, install Transformers.js from [NPM](https://www.npmjs.com/package/@huggingface/transformers) with the following command:
48
+
49
+ ```bash
50
+ npm install @huggingface/transformers
51
+ ```
52
+
53
+ For this application, we will use the [Xenova/nllb-200-distilled-600M](https://huggingface.co/Xenova/nllb-200-distilled-600M) model, which can perform multilingual translation among 200 languages. Before we start, there are 2 things we need to take note of:
54
+ 1. ML inference can be quite computationally intensive, so it's better to load and run the models in a separate thread from the main (UI) thread.
55
+ 2. Since the model is quite large (>1 GB), we don't want to download it until the user clicks the "Translate" button.
56
+
57
+ We can achieve both of these goals by using a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers) and some [React hooks](https://react.dev/reference/react).
58
+
59
+ 1. Create a file called `worker.js` in the `src` directory. This script will do all the heavy-lifing for us, including loading and running of the translation pipeline. To ensure the model is only loaded once, we will create the `MyTranslationPipeline` class which use the [singleton pattern](https://en.wikipedia.org/wiki/Singleton_pattern) to lazily create a single instance of the pipeline when `getInstance` is first called, and use this pipeline for all subsequent calls:
60
+ ```javascript
61
+ import { pipeline, TextStreamer } from '@huggingface/transformers';
62
+
63
+ class MyTranslationPipeline {
64
+ static task = 'translation';
65
+ static model = 'Xenova/nllb-200-distilled-600M';
66
+ static instance = null;
67
+
68
+ static async getInstance(progress_callback = null) {
69
+ this.instance ??= pipeline(this.task, this.model, { progress_callback });
70
+ return this.instance;
71
+ }
72
+ }
73
+ ```
74
+
75
+ 2. Modify `App.jsx` in the `src` directory. This file is automatically created when initializing our React project, and will contain some boilerplate code. Inside the `App` function, let's create the web worker and store a reference to it using the `useRef` hook:
76
+ ```jsx
77
+ // Remember to import the relevant hooks
78
+ import { useEffect, useRef, useState } from 'react'
79
+ import './App.css'
80
+
81
+ function App() {
82
+ // Create a reference to the worker object.
83
+ const worker = useRef(null);
84
+
85
+ // We use the `useEffect` hook to setup the worker as soon as the `App` component is mounted.
86
+ useEffect(() => {
87
+ // Create the worker if it does not yet exist.
88
+ worker.current ??= new Worker(new URL('./worker.js', import.meta.url), {
89
+ type: 'module'
90
+ });
91
+
92
+ // Create a callback function for messages from the worker thread.
93
+ const onMessageReceived = (e) => {
94
+ // TODO: Will fill in later
95
+ };
96
+
97
+ // Attach the callback function as an event listener.
98
+ worker.current.addEventListener('message', onMessageReceived);
99
+
100
+ // Define a cleanup function for when the component is unmounted.
101
+ return () => worker.current.removeEventListener('message', onMessageReceived);
102
+ });
103
+
104
+ return (
105
+ // TODO: Rest of our app goes here...
106
+ )
107
+ }
108
+
109
+ export default App
110
+
111
+ ```
112
+
113
+
114
+ ## Step 3: Design the user interface
115
+
116
+ <Tip>
117
+
118
+ We recommend starting the development server again with `npm run dev`
119
+ (if not already running) so that you can see your changes in real-time.
120
+
121
+ </Tip>
122
+
123
+
124
+
125
+ First, let's define our components. Create a folder called `components` in the `src` directory, and create the following files:
126
+ 1. `LanguageSelector.jsx`: This component will allow the user to select the input and output languages. Check out the full list of languages [here](https://github.com/huggingface/transformers.js-examples/tree/main/react-translator/src/components/LanguageSelector.jsx).
127
+ ```jsx
128
+ const LANGUAGES = {
129
+ "Acehnese (Arabic script)": "ace_Arab",
130
+ "Acehnese (Latin script)": "ace_Latn",
131
+ "Afrikaans": "afr_Latn",
132
+ ...
133
+ "Zulu": "zul_Latn",
134
+ }
135
+
136
+ export default function LanguageSelector({ type, onChange, defaultLanguage }) {
137
+ return (
138
+ <div className='language-selector'>
139
+ <label>{type}: </label>
140
+ <select onChange={onChange} defaultValue={defaultLanguage}>
141
+ {Object.entries(LANGUAGES).map(([key, value]) => {
142
+ return <option key={key} value={value}>{key}</option>
143
+ })}
144
+ </select>
145
+ </div>
146
+ )
147
+ }
148
+ ```
149
+
150
+
151
+ 2. `Progress.jsx`: This component will display the progress for downloading each model file.
152
+ ```jsx
153
+ export default function Progress({ text, percentage }) {
154
+ percentage = percentage ?? 0;
155
+ return (
156
+ <div className="progress-container">
157
+ <div className='progress-bar' style={{ 'width': `${percentage}%` }}>
158
+ {text} ({`${percentage.toFixed(2)}%`})
159
+ </div>
160
+ </div>
161
+ );
162
+ }
163
+ ```
164
+
165
+ We can now use these components in `App.jsx` by adding these imports to the top of the file:
166
+ ```jsx
167
+ import LanguageSelector from './components/LanguageSelector';
168
+ import Progress from './components/Progress';
169
+ ```
170
+
171
+ Let's also add some state variables to keep track of a few things in our application, like model loading, languages, input text, and output text. Add the following code to the beginning of the `App` function in `src/App.jsx`:
172
+ ```jsx
173
+ function App() {
174
+
175
+ // Model loading
176
+ const [ready, setReady] = useState(null);
177
+ const [disabled, setDisabled] = useState(false);
178
+ const [progressItems, setProgressItems] = useState([]);
179
+
180
+ // Inputs and outputs
181
+ const [input, setInput] = useState('I love walking my dog.');
182
+ const [sourceLanguage, setSourceLanguage] = useState('eng_Latn');
183
+ const [targetLanguage, setTargetLanguage] = useState('fra_Latn');
184
+ const [output, setOutput] = useState('');
185
+
186
+ // rest of the code...
187
+ }
188
+ ```
189
+
190
+
191
+ Next, we can add our custom components to the main `App` component. We will also add two `textarea` elements for input and output text, and a `button` to trigger the translation. Modify the `return` statement to look like this:
192
+
193
+ ```jsx
194
+ return (
195
+ <>
196
+ <h1>Transformers.js</h1>
197
+ <h2>ML-powered multilingual translation in React!</h2>
198
+
199
+ <div className='container'>
200
+ <div className='language-container'>
201
+ <LanguageSelector type={"Source"} defaultLanguage={"eng_Latn"} onChange={x => setSourceLanguage(x.target.value)} />
202
+ <LanguageSelector type={"Target"} defaultLanguage={"fra_Latn"} onChange={x => setTargetLanguage(x.target.value)} />
203
+ </div>
204
+
205
+ <div className='textbox-container'>
206
+ <textarea value={input} rows={3} onChange={e => setInput(e.target.value)}></textarea>
207
+ <textarea value={output} rows={3} readOnly></textarea>
208
+ </div>
209
+ </div>
210
+
211
+ <button disabled={disabled} onClick={translate}>Translate</button>
212
+
213
+ <div className='progress-bars-container'>
214
+ {ready === false && (
215
+ <label>Loading models... (only run once)</label>
216
+ )}
217
+ {progressItems.map(data => (
218
+ <div key={data.file}>
219
+ <Progress text={data.file} percentage={data.progress} />
220
+ </div>
221
+ ))}
222
+ </div>
223
+ </>
224
+ )
225
+ ```
226
+
227
+ Don't worry about the `translate` function for now. We will define it in the next section.
228
+
229
+ Finally, we can add some CSS to make our app look a little nicer. Modify the following files in the `src` directory:
230
+ 1. `index.css`:
231
+ <details>
232
+ <summary>View code</summary>
233
+
234
+ ```css
235
+ :root {
236
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
237
+ line-height: 1.5;
238
+ font-weight: 400;
239
+ color: #213547;
240
+ background-color: #ffffff;
241
+
242
+ font-synthesis: none;
243
+ text-rendering: optimizeLegibility;
244
+ -webkit-font-smoothing: antialiased;
245
+ -moz-osx-font-smoothing: grayscale;
246
+ -webkit-text-size-adjust: 100%;
247
+ }
248
+
249
+ body {
250
+ margin: 0;
251
+ display: flex;
252
+ place-items: center;
253
+ min-width: 320px;
254
+ min-height: 100vh;
255
+ }
256
+
257
+ h1 {
258
+ font-size: 3.2em;
259
+ line-height: 1;
260
+ }
261
+
262
+ h1,
263
+ h2 {
264
+ margin: 8px;
265
+ }
266
+
267
+ select {
268
+ padding: 0.3em;
269
+ cursor: pointer;
270
+ }
271
+
272
+ textarea {
273
+ padding: 0.6em;
274
+ }
275
+
276
+ button {
277
+ padding: 0.6em 1.2em;
278
+ cursor: pointer;
279
+ font-weight: 500;
280
+ }
281
+
282
+ button[disabled] {
283
+ cursor: not-allowed;
284
+ }
285
+
286
+ select,
287
+ textarea,
288
+ button {
289
+ border-radius: 8px;
290
+ border: 1px solid transparent;
291
+ font-size: 1em;
292
+ font-family: inherit;
293
+ background-color: #f9f9f9;
294
+ transition: border-color 0.25s;
295
+ }
296
+
297
+ select:hover,
298
+ textarea:hover,
299
+ button:not([disabled]):hover {
300
+ border-color: #646cff;
301
+ }
302
+
303
+ select:focus,
304
+ select:focus-visible,
305
+ textarea:focus,
306
+ textarea:focus-visible,
307
+ button:focus,
308
+ button:focus-visible {
309
+ outline: 4px auto -webkit-focus-ring-color;
310
+ }
311
+ ```
312
+ </details>
313
+
314
+ 1. `App.css`
315
+ <details>
316
+ <summary>View code</summary>
317
+
318
+ ```css
319
+ #root {
320
+ max-width: 1280px;
321
+ margin: 0 auto;
322
+ padding: 2rem;
323
+ text-align: center;
324
+ }
325
+
326
+ .language-container {
327
+ display: flex;
328
+ gap: 20px;
329
+ }
330
+
331
+ .textbox-container {
332
+ display: flex;
333
+ justify-content: center;
334
+ gap: 20px;
335
+ width: 800px;
336
+ }
337
+
338
+ .textbox-container>textarea, .language-selector {
339
+ width: 50%;
340
+ }
341
+
342
+ .language-selector>select {
343
+ width: 150px;
344
+ }
345
+
346
+ .progress-container {
347
+ position: relative;
348
+ font-size: 14px;
349
+ color: white;
350
+ background-color: #e9ecef;
351
+ border: solid 1px;
352
+ border-radius: 8px;
353
+ text-align: left;
354
+ overflow: hidden;
355
+ }
356
+
357
+ .progress-bar {
358
+ padding: 0 4px;
359
+ z-index: 0;
360
+ top: 0;
361
+ width: 1%;
362
+ overflow: hidden;
363
+ background-color: #007bff;
364
+ white-space: nowrap;
365
+ }
366
+
367
+ .progress-text {
368
+ z-index: 2;
369
+ }
370
+
371
+ .selector-container {
372
+ display: flex;
373
+ gap: 20px;
374
+ }
375
+
376
+ .progress-bars-container {
377
+ padding: 8px;
378
+ height: 140px;
379
+ }
380
+
381
+ .container {
382
+ margin: 25px;
383
+ display: flex;
384
+ flex-direction: column;
385
+ gap: 10px;
386
+ }
387
+ ```
388
+ </details>
389
+
390
+ ## Step 4: Connecting everything together
391
+
392
+
393
+ Now that we have a basic user interface set up, we can finally connect everything together.
394
+
395
+ First, let's define the `translate` function, which will be called when the user clicks the `Translate` button. This sends a message (containing the input text, source language, and target language) to the worker thread for processing. We will also disable the button so the user doesn't click it multiple times. Add the following code just before the `return` statement in the `App` function:
396
+
397
+ ```jsx
398
+ const translate = () => {
399
+ setDisabled(true);
400
+ setOutput('');
401
+ worker.current.postMessage({
402
+ text: input,
403
+ src_lang: sourceLanguage,
404
+ tgt_lang: targetLanguage,
405
+ });
406
+ }
407
+ ```
408
+
409
+ Now, let's add an event listener in `src/worker.js` to listen for messages from the main thread. We will send back messages (e.g., for model loading progress and text streaming) to the main thread with `self.postMessage`.
410
+
411
+ ```javascript
412
+ // Listen for messages from the main thread
413
+ self.addEventListener('message', async (event) => {
414
+ // Retrieve the translation pipeline. When called for the first time,
415
+ // this will load the pipeline and save it for future use.
416
+ const translator = await MyTranslationPipeline.getInstance(x => {
417
+ // We also add a progress callback to the pipeline so that we can
418
+ // track model loading.
419
+ self.postMessage(x);
420
+ });
421
+
422
+ // Capture partial output as it streams from the pipeline
423
+ const streamer = new TextStreamer(translator.tokenizer, {
424
+ skip_prompt: true,
425
+ skip_special_tokens: true,
426
+ callback_function: function (text) {
427
+ self.postMessage({
428
+ status: 'update',
429
+ output: text
430
+ });
431
+ }
432
+ });
433
+
434
+ // Actually perform the translation
435
+ const output = await translator(event.data.text, {
436
+ tgt_lang: event.data.tgt_lang,
437
+ src_lang: event.data.src_lang,
438
+
439
+ // Allows for partial output to be captured
440
+ streamer,
441
+ });
442
+
443
+ // Send the output back to the main thread
444
+ self.postMessage({
445
+ status: 'complete',
446
+ output,
447
+ });
448
+ });
449
+ ```
450
+
451
+ Finally, let's fill in our `onMessageReceived` function in `src/App.jsx`, which will update the application state in response to messages from the worker thread. Add the following code inside the `useEffect` hook we defined earlier:
452
+
453
+ ```jsx
454
+ const onMessageReceived = (e) => {
455
+ switch (e.data.status) {
456
+ case 'initiate':
457
+ // Model file start load: add a new progress item to the list.
458
+ setReady(false);
459
+ setProgressItems(prev => [...prev, e.data]);
460
+ break;
461
+
462
+ case 'progress':
463
+ // Model file progress: update one of the progress items.
464
+ setProgressItems(
465
+ prev => prev.map(item => {
466
+ if (item.file === e.data.file) {
467
+ return { ...item, progress: e.data.progress }
468
+ }
469
+ return item;
470
+ })
471
+ );
472
+ break;
473
+
474
+ case 'done':
475
+ // Model file loaded: remove the progress item from the list.
476
+ setProgressItems(
477
+ prev => prev.filter(item => item.file !== e.data.file)
478
+ );
479
+ break;
480
+
481
+ case 'ready':
482
+ // Pipeline ready: the worker is ready to accept messages.
483
+ setReady(true);
484
+ break;
485
+
486
+ case 'update':
487
+ // Generation update: update the output text.
488
+ setOutput(o => o + e.data.output);
489
+ break;
490
+
491
+ case 'complete':
492
+ // Generation complete: re-enable the "Translate" button
493
+ setDisabled(false);
494
+ break;
495
+ }
496
+ };
497
+ ```
498
+
499
+ You can now run the application with `npm run dev` and perform multilingual translation directly in your browser!
500
+
501
+
502
+
503
+ ## (Optional) Step 5: Build and deploy
504
+
505
+ To build your application, simply run `npm run build`. This will bundle your application and output the static files to the `dist` folder.
506
+
507
+ For this demo, we will deploy our application as a static [Hugging Face Space](https://huggingface.co/docs/hub/spaces), but you can deploy it anywhere you like! If you haven't already, you can create a free Hugging Face account [here](https://huggingface.co/join).
508
+
509
+ 1. Visit [https://huggingface.co/new-space](https://huggingface.co/new-space) and fill in the form. Remember to select "Static" as the space type.
510
+ 2. Go to "Files" &rarr; "Add file" &rarr; "Upload files". Drag the `index.html` file and `public/` folder from the `dist` folder into the upload box and click "Upload". After they have uploaded, scroll down to the button and click "Commit changes to main".
511
+
512
+ **That's it!** Your application should now be live at `https://huggingface.co/spaces/<your-username>/<your-space-name>`!
src/App.tsx CHANGED
@@ -1,24 +1,213 @@
1
- import React from 'react';
2
- import logo from './logo.svg';
3
- import './App.css';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  function App() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  return (
7
- <div className="App">
8
- <header className="App-header">
9
- <img src={logo} className="App-logo" alt="logo" />
10
- <p>
11
- Edit <code>src/App.tsx</code> and save to reload.
12
- </p>
13
- <a
14
- className="App-link"
15
- href="https://reactjs.org"
16
- target="_blank"
17
- rel="noopener noreferrer"
18
  >
19
- Learn React
20
- </a>
21
- </header>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  </div>
23
  );
24
  }
 
1
+ // src/App.tsx
2
+ import { useState, useRef, useEffect, useCallback } from "react";
3
+ import { Section, WorkerMessage, WorkerInput } from "./types";
4
+
5
+ const PLACEHOLDER_REVIEWS: string[] = [
6
+ // battery/charging problems
7
+ "Disappointed with the battery life! The phone barely lasts half a day with regular use. Considering how much I paid for it, I expected better performance in this department.",
8
+ "I bought this phone a week ago, and I'm already frustrated with the battery life. It barely lasts half a day with normal usage. I expected more from a supposedly high-end device",
9
+ "The charging port is so finicky. Sometimes it takes forever to charge, and other times it doesn't even recognize the charger. Frustrating experience!",
10
+
11
+ // overheating
12
+ "This phone heats up way too quickly, especially when using demanding apps. It's uncomfortable to hold, and I'm concerned it might damage the internal components over time. Not what I expected",
13
+ "This phone is like holding a hot potato. Video calls turn it into a scalding nightmare. Seriously, can't it keep its cool?",
14
+ "Forget about a heatwave outside; my phone's got its own. It's like a little portable heater. Not what I signed up for.",
15
+
16
+ // poor build quality
17
+ "I dropped the phone from a short distance, and the screen cracked easily. Not as durable as I expected from a flagship device.",
18
+ "Took a slight bump in my bag, and the frame got dinged. Are we back in the flip phone era?",
19
+ "So, my phone's been in my pocket with just keys – no ninja moves or anything. Still, it managed to get some scratches. Disappointed with the build quality.",
20
+
21
+ // software
22
+ "The software updates are a nightmare. Each update seems to introduce new bugs, and it takes forever for them to be fixed.",
23
+ "Constant crashes and freezes make me want to throw it into a black hole.",
24
+ "Every time I open Instagram, my phone freezes and crashes. It's so frustrating!",
25
+
26
+ // other
27
+ "I'm not sure what to make of this phone. It's not bad, but it's not great either. I'm on the fence about it.",
28
+ "I hate the color of this phone. It's so ugly!",
29
+ "This phone sucks! I'm returning it.",
30
+ ].sort(() => Math.random() - 0.5);
31
+
32
+ const PLACEHOLDER_SECTIONS: string[] = [
33
+ "Battery and charging problems",
34
+ "Overheating",
35
+ "Poor build quality",
36
+ "Software issues",
37
+ "Other",
38
+ ];
39
 
40
  function App() {
41
+ const [text, setText] = useState<string>(PLACEHOLDER_REVIEWS.join("\n"));
42
+
43
+ const [sections, setSections] = useState<Section[]>(
44
+ PLACEHOLDER_SECTIONS.map((title) => ({ title, items: [] })),
45
+ );
46
+
47
+ const [status, setStatus] = useState<string>("idle");
48
+
49
+ // Create a reference to the worker object.
50
+ const worker = useRef<Worker | null>(null);
51
+
52
+ // We use the `useEffect` hook to setup the worker as soon as the `App` component is mounted.
53
+ useEffect(() => {
54
+ if (!worker.current) {
55
+ // Create the worker if it does not yet exist.
56
+ worker.current = new Worker(new URL("./worker.js", import.meta.url), {
57
+ type: "module",
58
+ });
59
+ }
60
+
61
+ // Create a callback function for messages from the worker thread.
62
+ const onMessageReceived = (e: MessageEvent<WorkerMessage>) => {
63
+ const status = e.data.status;
64
+ if (status === "initiate") {
65
+ setStatus("loading");
66
+ } else if (status === "ready") {
67
+ setStatus("ready");
68
+ } else if (status === "output") {
69
+ const { sequence, labels, scores } = e.data.output!;
70
+
71
+ // Threshold for classification
72
+ const label = scores[0] > 0.5 ? labels[0] : "Other";
73
+
74
+ const sectionID =
75
+ sections.map((x) => x.title).indexOf(label) ?? sections.length - 1;
76
+ setSections((sections) => {
77
+ const newSections = [...sections];
78
+ newSections[sectionID] = {
79
+ ...newSections[sectionID],
80
+ items: [...newSections[sectionID].items, sequence],
81
+ };
82
+ return newSections;
83
+ });
84
+ } else if (status === "complete") {
85
+ setStatus("idle");
86
+ }
87
+ };
88
+
89
+ // Attach the callback function as an event listener.
90
+ worker.current.addEventListener("message", onMessageReceived);
91
+
92
+ // Define a cleanup function for when the component is unmounted.
93
+ return () =>
94
+ worker.current?.removeEventListener("message", onMessageReceived);
95
+ }, [sections]);
96
+
97
+ const classify = useCallback(() => {
98
+ setStatus("processing");
99
+ const message: WorkerInput = {
100
+ text,
101
+ labels: sections
102
+ .slice(0, sections.length - 1)
103
+ .map((section) => section.title),
104
+ };
105
+ worker.current?.postMessage(message);
106
+ }, [text, sections]);
107
+
108
+ const busy: boolean = status !== "idle";
109
+
110
+ const handleAddCategory = (): void => {
111
+ setSections((sections) => {
112
+ const newSections = [...sections];
113
+ // add at position 2 from the end
114
+ newSections.splice(newSections.length - 1, 0, {
115
+ title: "New Category",
116
+ items: [],
117
+ });
118
+ return newSections;
119
+ });
120
+ };
121
+
122
+ const handleRemoveCategory = (): void => {
123
+ setSections((sections) => {
124
+ const newSections = [...sections];
125
+ newSections.splice(newSections.length - 2, 1); // Remove second last element
126
+ return newSections;
127
+ });
128
+ };
129
+
130
+ const handleClear = (): void => {
131
+ setSections((sections) =>
132
+ sections.map((section) => ({
133
+ ...section,
134
+ items: [],
135
+ })),
136
+ );
137
+ };
138
+
139
+ const handleSectionTitleChange = (index: number, newTitle: string): void => {
140
+ setSections((sections) => {
141
+ const newSections = [...sections];
142
+ newSections[index].title = newTitle;
143
+ return newSections;
144
+ });
145
+ };
146
+
147
  return (
148
+ <div className="flex flex-col h-screen w-screen p-1">
149
+ <textarea
150
+ className="border w-full p-1 h-1/2"
151
+ value={text}
152
+ onChange={(e) => setText(e.target.value)}
153
+ ></textarea>
154
+ <div className="flex flex-col justify-center items-center m-2 gap-1">
155
+ <button
156
+ className="border py-1 px-2 bg-blue-400 rounded text-white text-lg font-medium disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer"
157
+ disabled={busy}
158
+ onClick={classify}
159
  >
160
+ {!busy
161
+ ? "Categorize"
162
+ : status === "loading"
163
+ ? "Model loading..."
164
+ : "Processing"}
165
+ </button>
166
+ <div className="flex gap-1">
167
+ <button
168
+ className="border py-1 px-2 bg-green-400 rounded text-white text-sm font-medium cursor-pointer"
169
+ onClick={handleAddCategory}
170
+ >
171
+ Add category
172
+ </button>
173
+ <button
174
+ className="border py-1 px-2 bg-red-400 rounded text-white text-sm font-medium cursor-pointer"
175
+ disabled={sections.length <= 1}
176
+ onClick={handleRemoveCategory}
177
+ >
178
+ Remove category
179
+ </button>
180
+ <button
181
+ className="border py-1 px-2 bg-orange-400 rounded text-white text-sm font-medium cursor-pointer"
182
+ onClick={handleClear}
183
+ >
184
+ Clear
185
+ </button>
186
+ </div>
187
+ </div>
188
+
189
+ <div className="flex justify-between flex-grow overflow-x-auto max-h-[40%]">
190
+ {sections.map((section, index) => (
191
+ <div key={index} className="flex flex-col w-full">
192
+ <input
193
+ disabled={section.title === "Other"}
194
+ className="w-full border px-1 text-center"
195
+ value={section.title}
196
+ onChange={(e) => handleSectionTitleChange(index, e.target.value)}
197
+ ></input>
198
+ <div className="overflow-y-auto h-full border">
199
+ {section.items.map((item, itemIndex) => (
200
+ <div
201
+ className="m-2 border bg-red-50 rounded p-1 text-sm"
202
+ key={itemIndex}
203
+ >
204
+ {item}
205
+ </div>
206
+ ))}
207
+ </div>
208
+ </div>
209
+ ))}
210
+ </div>
211
  </div>
212
  );
213
  }
src/components/PipelineSelector.tsx ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import React from 'react';
3
+
4
+ const pipelines = [
5
+ 'text-classification',
6
+ 'image-classification',
7
+ 'question-answering',
8
+ 'translation',
9
+ ];
10
+
11
+ interface PipelineSelectorProps {
12
+ onPipelineSelect: (pipeline: string) => void;
13
+ }
14
+
15
+ const PipelineSelector: React.FC<PipelineSelectorProps> = ({ onPipelineSelect }) => {
16
+ return (
17
+ <select onChange={(e) => onPipelineSelect(e.target.value)}>
18
+ <option value="">Select a pipeline</option>
19
+ {pipelines.map((pipeline) => (
20
+ <option key={pipeline} value={pipeline}>
21
+ {pipeline}
22
+ </option>
23
+ ))}
24
+ </select>
25
+ );
26
+ };
27
+
28
+ export default PipelineSelector;
src/types.ts ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export interface Section {
2
+ title: string;
3
+ items: string[];
4
+ }
5
+
6
+ export interface ClassificationOutput {
7
+ sequence: string;
8
+ labels: string[];
9
+ scores: number[];
10
+ }
11
+
12
+ export interface WorkerMessage {
13
+ status: 'initiate' | 'ready' | 'output' | 'complete';
14
+ output?: ClassificationOutput;
15
+ }
16
+
17
+ export interface WorkerInput {
18
+ text: string;
19
+ labels: string[];
20
+ }
21
+
22
+ export type AppStatus = 'idle' | 'loading' | 'processing';
src/worker.js ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable no-restricted-globals */
2
+ import { pipeline } from "@huggingface/transformers";
3
+
4
+ class MyZeroShotClassificationPipeline {
5
+ static task = "zero-shot-classification";
6
+ static model = "MoritzLaurer/deberta-v3-xsmall-zeroshot-v1.1-all-33";
7
+ static instance = null;
8
+
9
+ static async getInstance(progress_callback = null) {
10
+ this.instance ??= pipeline(this.task, this.model, {
11
+ progress_callback,
12
+ });
13
+
14
+ return this.instance;
15
+ }
16
+ }
17
+
18
+ // Listen for messages from the main thread
19
+ self.addEventListener("message", async (event) => {
20
+ // Retrieve the pipeline. When called for the first time,
21
+ // this will load the pipeline and save it for future use.
22
+ const classifier = await MyZeroShotClassificationPipeline.getInstance((x) => {
23
+ // We also add a progress callback to the pipeline so that we can
24
+ // track model loading.
25
+ self.postMessage(x);
26
+ });
27
+
28
+ const { text, labels } = event.data;
29
+
30
+ const split = text.split("\n");
31
+ for (const line of split) {
32
+ const output = await classifier(line, labels, {
33
+ hypothesis_template: "This text is about {}.",
34
+ multi_label: true,
35
+ });
36
+ // Send the output back to the main thread
37
+ self.postMessage({ status: "output", output });
38
+ }
39
+ // Send the output back to the main thread
40
+ self.postMessage({ status: "complete" });
41
+ });