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/diagnostics@2.0.3':
881
  resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==}
882
 
 
 
 
883
  '@eslint-community/eslint-utils@4.7.0':
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/config-array@0.13.0':
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/cliui@8.0.2':
915
  resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
916
  engines: {node: '>=12'}
917
 
 
 
 
 
918
  '@istanbuljs/load-nyc-config@1.1.0':
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/plugin-babel@5.3.1':
1061
  resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
1062
  engines: {node: '>= 10.0.0'}
@@ -1770,6 +1933,10 @@ packages:
1770
  boolbase@1.0.0:
1771
  resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
1772
 
 
 
 
 
1773
  brace-expansion@1.1.12:
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
  chrome-trace-event@1.0.4:
1878
  resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
1879
  engines: {node: '>=6.0'}
@@ -1922,6 +2093,10 @@ packages:
1922
  color@3.2.1:
1923
  resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==}
1924
 
 
 
 
 
1925
  colord@2.9.3:
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
  detect-newline@3.1.0:
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
  escalade@3.2.0:
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
  flatted@3.3.3:
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
  global-modules@2.0.0:
2855
  resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==}
2856
  engines: {node: '>=6'}
@@ -2881,6 +3070,9 @@ packages:
2881
  graphemer@1.4.0:
2882
  resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
2883
 
 
 
 
2884
  gzip-size@6.0.0:
2885
  resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
2886
  engines: {node: '>=10'}
@@ -3502,6 +3694,9 @@ packages:
3502
  json-stable-stringify-without-jsonify@1.0.1:
3503
  resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
3504
 
 
 
 
3505
  json5@1.0.2:
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
  loose-envify@1.4.0:
3630
  resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
3631
  hasBin: true
@@ -3657,6 +3855,10 @@ packages:
3657
  makeerror@1.0.12:
3658
  resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
3659
 
 
 
 
 
3660
  math-intrinsics@1.1.0:
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
  mkdirp@0.5.6:
3749
  resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
3750
  hasBin: true
3751
 
 
 
 
 
 
3752
  moo-server@1.3.0:
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
  open@8.4.2:
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
  possible-typed-array-names@1.1.0:
4018
  resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
4019
  engines: {node: '>= 0.4'}
@@ -4487,6 +4714,10 @@ packages:
4487
  prop-types@15.8.1:
4488
  resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
4489
 
 
 
 
 
4490
  proxy-addr@2.0.7:
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
  rollup-plugin-terser@7.0.2:
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
  semver@6.3.1:
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
  serialize-javascript@4.0.0:
4814
  resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==}
4815
 
@@ -4842,6 +5084,10 @@ packages:
4842
  setprototypeof@1.2.0:
4843
  resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
4844
 
 
 
 
 
4845
  shebang-command@2.0.0:
4846
  resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
4847
  engines: {node: '>=8'}
@@ -4936,6 +5182,9 @@ packages:
4936
  sprintf-js@1.0.3:
4937
  resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
4938
 
 
 
 
4939
  stable@0.1.8:
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
  temp-dir@2.0.0:
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
  type-fest@0.16.0:
5239
  resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==}
5240
  engines: {node: '>=10'}
@@ -5614,6 +5871,10 @@ packages:
5614
  yallist@3.1.1:
5615
  resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
5616
 
 
 
 
 
5617
  yaml@1.10.2:
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/eslint-utils@4.7.0(eslint@8.57.1)':
6641
  dependencies:
6642
  eslint: 8.57.1
@@ -6660,6 +6926,15 @@ snapshots:
6660
 
6661
  '@eslint/js@8.57.1': {}
6662
 
 
 
 
 
 
 
 
 
 
6663
  '@humanwhocodes/config-array@0.13.0':
6664
  dependencies:
6665
  '@humanwhocodes/object-schema': 2.0.3
@@ -6672,6 +6947,87 @@ snapshots:
6672
 
6673
  '@humanwhocodes/object-schema@2.0.3': {}
6674
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6675
  '@isaacs/cliui@8.0.2':
6676
  dependencies:
6677
  string-width: 5.1.2
@@ -6681,6 +7037,10 @@ snapshots:
6681
  wrap-ansi: 8.1.0
6682
  wrap-ansi-cjs: wrap-ansi@7.0.0
6683
 
 
 
 
 
6684
  '@istanbuljs/load-nyc-config@1.1.0':
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(webpack@5.99.9)
6925
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6926
  '@rollup/plugin-babel@5.3.1(@babel/core@7.28.0)(@types/babel__core@7.20.5)(rollup@2.79.2)':
6927
  dependencies:
6928
  '@babel/core': 7.28.0
@@ -7828,6 +8211,8 @@ snapshots:
7828
 
7829
  boolbase@1.0.0: {}
7830
 
 
 
7831
  brace-expansion@1.1.12:
7832
  dependencies:
7833
  balanced-match: 1.0.2
@@ -7948,6 +8333,8 @@ snapshots:
7948
  optionalDependencies:
7949
  fsevents: 2.3.3
7950
 
 
 
7951
  chrome-trace-event@1.0.4: {}
7952
 
7953
  ci-info@3.9.0: {}
@@ -7996,6 +8383,11 @@ snapshots:
7996
  color-convert: 1.9.3
7997
  color-string: 1.9.1
7998
 
 
 
 
 
 
7999
  colord@2.9.3: {}
8000
 
8001
  colorette@2.0.20: {}
@@ -8303,6 +8695,8 @@ snapshots:
8303
 
8304
  destroy@1.2.0: {}
8305
 
 
 
8306
  detect-newline@3.1.0: {}
8307
 
8308
  detect-node@2.1.0: {}
@@ -8541,6 +8935,8 @@ snapshots:
8541
  is-date-object: 1.1.0
8542
  is-symbol: 1.1.1
8543
 
 
 
8544
  escalade@3.2.0: {}
8545
 
8546
  escape-html@1.0.3: {}
@@ -8958,6 +9354,8 @@ snapshots:
8958
  keyv: 4.5.4
8959
  rimraf: 3.0.2
8960
 
 
 
8961
  flatted@3.3.3: {}
8962
 
8963
  fn.name@1.1.0: {}
@@ -9101,6 +9499,15 @@ snapshots:
9101
  once: 1.4.0
9102
  path-is-absolute: 1.0.1
9103
 
 
 
 
 
 
 
 
 
 
9104
  global-modules@2.0.0:
9105
  dependencies:
9106
  global-prefix: 3.0.0
@@ -9135,6 +9542,8 @@ snapshots:
9135
 
9136
  graphemer@1.4.0: {}
9137
 
 
 
9138
  gzip-size@6.0.0:
9139
  dependencies:
9140
  duplexer: 0.1.2
@@ -10009,6 +10418,8 @@ snapshots:
10009
 
10010
  json-stable-stringify-without-jsonify@1.0.1: {}
10011
 
 
 
10012
  json5@1.0.2:
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
  loose-envify@1.4.0:
10132
  dependencies:
10133
  js-tokens: 4.0.0
@@ -10160,6 +10573,10 @@ snapshots:
10160
  dependencies:
10161
  tmpl: 1.0.5
10162
 
 
 
 
 
10163
  math-intrinsics@1.1.0: {}
10164
 
10165
  mdn-data@2.0.14: {}
@@ -10223,10 +10640,16 @@ snapshots:
10223
 
10224
  minipass@7.1.2: {}
10225
 
 
 
 
 
10226
  mkdirp@0.5.6:
10227
  dependencies:
10228
  minimist: 1.2.8
10229
 
 
 
10230
  moo-server@1.3.0: {}
10231
 
10232
  ms@2.0.0: {}
@@ -10361,6 +10784,25 @@ snapshots:
10361
  dependencies:
10362
  mimic-fn: 2.1.0
10363
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10364
  open@8.4.2:
10365
  dependencies:
10366
  define-lazy-prop: 2.0.0
@@ -10484,6 +10926,8 @@ snapshots:
10484
  dependencies:
10485
  find-up: 3.0.0
10486
 
 
 
10487
  possible-typed-array-names@1.1.0: {}
10488
 
10489
  postcss-attribute-case-insensitive@5.0.2(postcss@8.5.6):
@@ -10958,6 +11402,21 @@ snapshots:
10958
  object-assign: 4.1.1
10959
  react-is: 16.13.1
10960
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10961
  proxy-addr@2.0.7:
10962
  dependencies:
10963
  forwarded: 0.2.0
@@ -11275,6 +11734,15 @@ snapshots:
11275
  dependencies:
11276
  glob: 7.2.3
11277
 
 
 
 
 
 
 
 
 
 
11278
  rollup-plugin-terser@7.0.2(rollup@2.79.2):
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
  semver@6.3.1: {}
11370
 
11371
  semver@7.7.2: {}
@@ -11388,6 +11858,10 @@ snapshots:
11388
  transitivePeerDependencies:
11389
  - supports-color
11390
 
 
 
 
 
11391
  serialize-javascript@4.0.0:
11392
  dependencies:
11393
  randombytes: 2.1.0
@@ -11443,6 +11917,34 @@ snapshots:
11443
 
11444
  setprototypeof@1.2.0: {}
11445
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11446
  shebang-command@2.0.0:
11447
  dependencies:
11448
  shebang-regex: 3.0.0
@@ -11548,6 +12050,8 @@ snapshots:
11548
 
11549
  sprintf-js@1.0.3: {}
11550
 
 
 
11551
  stable@0.1.8: {}
11552
 
11553
  stack-trace@0.0.10: {}
@@ -11781,6 +12285,15 @@ snapshots:
11781
 
11782
  tapable@2.2.2: {}
11783
 
 
 
 
 
 
 
 
 
 
11784
  temp-dir@2.0.0: {}
11785
 
11786
  tempy@0.6.0:
@@ -11890,6 +12403,8 @@ snapshots:
11890
 
11891
  type-detect@4.0.8: {}
11892
 
 
 
11893
  type-fest@0.16.0: {}
11894
 
11895
  type-fest@0.20.2: {}
@@ -12400,6 +12915,8 @@ snapshots:
12400
 
12401
  yallist@3.1.1: {}
12402
 
 
 
12403
  yaml@1.10.2: {}
12404
 
12405
  yaml@2.8.0: {}
 
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/diagnostics@2.0.3':
884
  resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==}
885
 
886
+ '@emnapi/runtime@1.4.3':
887
+ resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==}
888
+
889
  '@eslint-community/eslint-utils@4.7.0':
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/jinja@0.4.1':
908
+ resolution: {integrity: sha512-3WXbMFaPkk03LRCM0z0sylmn8ddDm4ubjU7X+Hg4M2GOuMklwoGAFXp9V2keq7vltoB/c7McE5aHUVVddAewsw==}
909
+ engines: {node: '>=18'}
910
+
911
+ '@huggingface/transformers@3.6.1':
912
+ resolution: {integrity: sha512-cQVwrt/FawqGG/cDDT4+7Zdmw0HFignBirHsAUYI26HAj24oT2FxVyz2PgX6+qajutVLDekwhdChXxnZZB8XNg==}
913
+
914
  '@humanwhocodes/config-array@0.13.0':
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/sharp-darwin-arm64@0.34.2':
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/sharp-darwin-x64@0.34.2':
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/sharp-libvips-darwin-arm64@1.1.0':
940
+ resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==}
941
+ cpu: [arm64]
942
+ os: [darwin]
943
+
944
+ '@img/sharp-libvips-darwin-x64@1.1.0':
945
+ resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==}
946
+ cpu: [x64]
947
+ os: [darwin]
948
+
949
+ '@img/sharp-libvips-linux-arm64@1.1.0':
950
+ resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==}
951
+ cpu: [arm64]
952
+ os: [linux]
953
+
954
+ '@img/sharp-libvips-linux-arm@1.1.0':
955
+ resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==}
956
+ cpu: [arm]
957
+ os: [linux]
958
+
959
+ '@img/sharp-libvips-linux-ppc64@1.1.0':
960
+ resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==}
961
+ cpu: [ppc64]
962
+ os: [linux]
963
+
964
+ '@img/sharp-libvips-linux-s390x@1.1.0':
965
+ resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==}
966
+ cpu: [s390x]
967
+ os: [linux]
968
+
969
+ '@img/sharp-libvips-linux-x64@1.1.0':
970
+ resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==}
971
+ cpu: [x64]
972
+ os: [linux]
973
+
974
+ '@img/sharp-libvips-linuxmusl-arm64@1.1.0':
975
+ resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==}
976
+ cpu: [arm64]
977
+ os: [linux]
978
+
979
+ '@img/sharp-libvips-linuxmusl-x64@1.1.0':
980
+ resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==}
981
+ cpu: [x64]
982
+ os: [linux]
983
+
984
+ '@img/sharp-linux-arm64@0.34.2':
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/sharp-linux-arm@0.34.2':
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/sharp-linux-s390x@0.34.2':
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/sharp-linux-x64@0.34.2':
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/sharp-linuxmusl-arm64@0.34.2':
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/sharp-linuxmusl-x64@0.34.2':
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/sharp-wasm32@0.34.2':
1021
+ resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==}
1022
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
1023
+ cpu: [wasm32]
1024
+
1025
+ '@img/sharp-win32-arm64@0.34.2':
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/sharp-win32-ia32@0.34.2':
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/sharp-win32-x64@0.34.2':
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/cliui@8.0.2':
1044
  resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
1045
  engines: {node: '>=12'}
1046
 
1047
+ '@isaacs/fs-minipass@4.0.1':
1048
+ resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
1049
+ engines: {node: '>=18.0.0'}
1050
+
1051
  '@istanbuljs/load-nyc-config@1.1.0':
1052
  resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==}
1053
  engines: {node: '>=8'}
 
1190
  webpack-plugin-serve:
1191
  optional: true
1192
 
1193
+ '@protobufjs/aspromise@1.1.2':
1194
+ resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
1195
+
1196
+ '@protobufjs/base64@1.1.2':
1197
+ resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
1198
+
1199
+ '@protobufjs/codegen@2.0.4':
1200
+ resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==}
1201
+
1202
+ '@protobufjs/eventemitter@1.1.0':
1203
+ resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==}
1204
+
1205
+ '@protobufjs/fetch@1.1.0':
1206
+ resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==}
1207
+
1208
+ '@protobufjs/float@1.0.2':
1209
+ resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
1210
+
1211
+ '@protobufjs/inquire@1.1.0':
1212
+ resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==}
1213
+
1214
+ '@protobufjs/path@1.1.2':
1215
+ resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
1216
+
1217
+ '@protobufjs/pool@1.1.0':
1218
+ resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
1219
+
1220
+ '@protobufjs/utf8@1.1.0':
1221
+ resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
1222
+
1223
  '@rollup/plugin-babel@5.3.1':
1224
  resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
1225
  engines: {node: '>= 10.0.0'}
 
1933
  boolbase@1.0.0:
1934
  resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
1935
 
1936
+ boolean@3.2.0:
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
  brace-expansion@1.1.12:
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
+ chownr@3.0.0:
2045
+ resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
2046
+ engines: {node: '>=18'}
2047
+
2048
  chrome-trace-event@1.0.4:
2049
  resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
2050
  engines: {node: '>=6.0'}
 
2093
  color@3.2.1:
2094
  resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==}
2095
 
2096
+ color@4.2.3:
2097
+ resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
2098
+ engines: {node: '>=12.5.0'}
2099
+
2100
  colord@2.9.3:
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
+ detect-libc@2.0.4:
2429
+ resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==}
2430
+ engines: {node: '>=8'}
2431
+
2432
  detect-newline@3.1.0:
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
+ es6-error@4.1.1:
2618
+ resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==}
2619
+
2620
  escalade@3.2.0:
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
+ flatbuffers@25.2.10:
2906
+ resolution: {integrity: sha512-7JlN9ZvLDG1McO3kbX0k4v+SUAg48L1rIwEvN6ZQl/eCtgJz9UylTMzE9wrmYrcorgxm3CX/3T/w5VAub99UUw==}
2907
+
2908
  flatted@3.3.3:
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
+ global-agent@3.0.0:
3040
+ resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==}
3041
+ engines: {node: '>=10.0'}
3042
+
3043
  global-modules@2.0.0:
3044
  resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==}
3045
  engines: {node: '>=6'}
 
3070
  graphemer@1.4.0:
3071
  resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
3072
 
3073
+ guid-typescript@1.0.9:
3074
+ resolution: {integrity: sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==}
3075
+
3076
  gzip-size@6.0.0:
3077
  resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
3078
  engines: {node: '>=10'}
 
3694
  json-stable-stringify-without-jsonify@1.0.1:
3695
  resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
3696
 
3697
+ json-stringify-safe@5.0.1:
3698
+ resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
3699
+
3700
  json5@1.0.2:
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
+ long@5.3.2:
3825
+ resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
3826
+
3827
  loose-envify@1.4.0:
3828
  resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
3829
  hasBin: true
 
3855
  makeerror@1.0.12:
3856
  resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
3857
 
3858
+ matcher@3.0.0:
3859
+ resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
3860
+ engines: {node: '>=10'}
3861
+
3862
  math-intrinsics@1.1.0:
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
+ minizlib@3.0.2:
3951
+ resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==}
3952
+ engines: {node: '>= 18'}
3953
+
3954
  mkdirp@0.5.6:
3955
  resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
3956
  hasBin: true
3957
 
3958
+ mkdirp@3.0.1:
3959
+ resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==}
3960
+ engines: {node: '>=10'}
3961
+ hasBin: true
3962
+
3963
  moo-server@1.3.0:
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
+ onnxruntime-common@1.21.0:
4102
+ resolution: {integrity: sha512-Q632iLLrtCAVOTO65dh2+mNbQir/QNTVBG3h/QdZBpns7mZ0RYbLRBgGABPbpU9351AgYy7SJf1WaeVwMrBFPQ==}
4103
+
4104
+ onnxruntime-common@1.22.0-dev.20250409-89f8206ba4:
4105
+ resolution: {integrity: sha512-vDJMkfCfb0b1A836rgHj+ORuZf4B4+cc2bASQtpeoJLueuFc5DuYwjIZUBrSvx/fO5IrLjLz+oTrB3pcGlhovQ==}
4106
+
4107
+ onnxruntime-node@1.21.0:
4108
+ resolution: {integrity: sha512-NeaCX6WW2L8cRCSqy3bInlo5ojjQqu2fD3D+9W5qb5irwxhEyWKXeH2vZ8W9r6VxaMPUan+4/7NDwZMtouZxEw==}
4109
+ os: [win32, darwin, linux]
4110
+
4111
+ onnxruntime-web@1.22.0-dev.20250409-89f8206ba4:
4112
+ resolution: {integrity: sha512-0uS76OPgH0hWCPrFKlL8kYVV7ckM7t/36HfbgoFw6Nd0CZVVbQC4PkrR8mBX8LtNUFZO25IQBqV2Hx2ho3FlbQ==}
4113
+
4114
  open@8.4.2:
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
+ platform@1.3.6:
4242
+ resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==}
4243
+
4244
  possible-typed-array-names@1.1.0:
4245
  resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
4246
  engines: {node: '>= 0.4'}
 
4714
  prop-types@15.8.1:
4715
  resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
4716
 
4717
+ protobufjs@7.5.3:
4718
+ resolution: {integrity: sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==}
4719
+ engines: {node: '>=12.0.0'}
4720
+
4721
  proxy-addr@2.0.7:
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
+ roarr@2.15.4:
4938
+ resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==}
4939
+ engines: {node: '>=8.0'}
4940
+
4941
  rollup-plugin-terser@7.0.2:
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
+ semver-compare@1.0.0:
5036
+ resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==}
5037
+
5038
  semver@6.3.1:
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
+ serialize-error@7.0.1:
5052
+ resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
5053
+ engines: {node: '>=10'}
5054
+
5055
  serialize-javascript@4.0.0:
5056
  resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==}
5057
 
 
5084
  setprototypeof@1.2.0:
5085
  resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
5086
 
5087
+ sharp@0.34.2:
5088
+ resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==}
5089
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
5090
+
5091
  shebang-command@2.0.0:
5092
  resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
5093
  engines: {node: '>=8'}
 
5182
  sprintf-js@1.0.3:
5183
  resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
5184
 
5185
+ sprintf-js@1.1.3:
5186
+ resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==}
5187
+
5188
  stable@0.1.8:
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
+ tar@7.4.3:
5369
+ resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==}
5370
+ engines: {node: '>=18'}
5371
+
5372
  temp-dir@2.0.0:
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
+ type-fest@0.13.1:
5492
+ resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
5493
+ engines: {node: '>=10'}
5494
+
5495
  type-fest@0.16.0:
5496
  resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==}
5497
  engines: {node: '>=10'}
 
5871
  yallist@3.1.1:
5872
  resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
5873
 
5874
+ yallist@5.0.0:
5875
+ resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
5876
+ engines: {node: '>=18'}
5877
+
5878
  yaml@1.10.2:
5879
  resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
5880
  engines: {node: '>= 6'}
 
6898
  enabled: 2.0.0
6899
  kuler: 2.0.0
6900
 
6901
+ '@emnapi/runtime@1.4.3':
6902
+ dependencies:
6903
+ tslib: 2.8.1
6904
+ optional: true
6905
+
6906
  '@eslint-community/eslint-utils@4.7.0(eslint@8.57.1)':
6907
  dependencies:
6908
  eslint: 8.57.1
 
6926
 
6927
  '@eslint/js@8.57.1': {}
6928
 
6929
+ '@huggingface/jinja@0.4.1': {}
6930
+
6931
+ '@huggingface/transformers@3.6.1':
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/config-array@0.13.0':
6939
  dependencies:
6940
  '@humanwhocodes/object-schema': 2.0.3
 
6947
 
6948
  '@humanwhocodes/object-schema@2.0.3': {}
6949
 
6950
+ '@img/sharp-darwin-arm64@0.34.2':
6951
+ optionalDependencies:
6952
+ '@img/sharp-libvips-darwin-arm64': 1.1.0
6953
+ optional: true
6954
+
6955
+ '@img/sharp-darwin-x64@0.34.2':
6956
+ optionalDependencies:
6957
+ '@img/sharp-libvips-darwin-x64': 1.1.0
6958
+ optional: true
6959
+
6960
+ '@img/sharp-libvips-darwin-arm64@1.1.0':
6961
+ optional: true
6962
+
6963
+ '@img/sharp-libvips-darwin-x64@1.1.0':
6964
+ optional: true
6965
+
6966
+ '@img/sharp-libvips-linux-arm64@1.1.0':
6967
+ optional: true
6968
+
6969
+ '@img/sharp-libvips-linux-arm@1.1.0':
6970
+ optional: true
6971
+
6972
+ '@img/sharp-libvips-linux-ppc64@1.1.0':
6973
+ optional: true
6974
+
6975
+ '@img/sharp-libvips-linux-s390x@1.1.0':
6976
+ optional: true
6977
+
6978
+ '@img/sharp-libvips-linux-x64@1.1.0':
6979
+ optional: true
6980
+
6981
+ '@img/sharp-libvips-linuxmusl-arm64@1.1.0':
6982
+ optional: true
6983
+
6984
+ '@img/sharp-libvips-linuxmusl-x64@1.1.0':
6985
+ optional: true
6986
+
6987
+ '@img/sharp-linux-arm64@0.34.2':
6988
+ optionalDependencies:
6989
+ '@img/sharp-libvips-linux-arm64': 1.1.0
6990
+ optional: true
6991
+
6992
+ '@img/sharp-linux-arm@0.34.2':
6993
+ optionalDependencies:
6994
+ '@img/sharp-libvips-linux-arm': 1.1.0
6995
+ optional: true
6996
+
6997
+ '@img/sharp-linux-s390x@0.34.2':
6998
+ optionalDependencies:
6999
+ '@img/sharp-libvips-linux-s390x': 1.1.0
7000
+ optional: true
7001
+
7002
+ '@img/sharp-linux-x64@0.34.2':
7003
+ optionalDependencies:
7004
+ '@img/sharp-libvips-linux-x64': 1.1.0
7005
+ optional: true
7006
+
7007
+ '@img/sharp-linuxmusl-arm64@0.34.2':
7008
+ optionalDependencies:
7009
+ '@img/sharp-libvips-linuxmusl-arm64': 1.1.0
7010
+ optional: true
7011
+
7012
+ '@img/sharp-linuxmusl-x64@0.34.2':
7013
+ optionalDependencies:
7014
+ '@img/sharp-libvips-linuxmusl-x64': 1.1.0
7015
+ optional: true
7016
+
7017
+ '@img/sharp-wasm32@0.34.2':
7018
+ dependencies:
7019
+ '@emnapi/runtime': 1.4.3
7020
+ optional: true
7021
+
7022
+ '@img/sharp-win32-arm64@0.34.2':
7023
+ optional: true
7024
+
7025
+ '@img/sharp-win32-ia32@0.34.2':
7026
+ optional: true
7027
+
7028
+ '@img/sharp-win32-x64@0.34.2':
7029
+ optional: true
7030
+
7031
  '@isaacs/cliui@8.0.2':
7032
  dependencies:
7033
  string-width: 5.1.2
 
7037
  wrap-ansi: 8.1.0
7038
  wrap-ansi-cjs: wrap-ansi@7.0.0
7039
 
7040
+ '@isaacs/fs-minipass@4.0.1':
7041
+ dependencies:
7042
+ minipass: 7.1.2
7043
+
7044
  '@istanbuljs/load-nyc-config@1.1.0':
7045
  dependencies:
7046
  camelcase: 5.3.1
 
7283
  type-fest: 0.21.3
7284
  webpack-dev-server: 4.15.2(webpack@5.99.9)
7285
 
7286
+ '@protobufjs/aspromise@1.1.2': {}
7287
+
7288
+ '@protobufjs/base64@1.1.2': {}
7289
+
7290
+ '@protobufjs/codegen@2.0.4': {}
7291
+
7292
+ '@protobufjs/eventemitter@1.1.0': {}
7293
+
7294
+ '@protobufjs/fetch@1.1.0':
7295
+ dependencies:
7296
+ '@protobufjs/aspromise': 1.1.2
7297
+ '@protobufjs/inquire': 1.1.0
7298
+
7299
+ '@protobufjs/float@1.0.2': {}
7300
+
7301
+ '@protobufjs/inquire@1.1.0': {}
7302
+
7303
+ '@protobufjs/path@1.1.2': {}
7304
+
7305
+ '@protobufjs/pool@1.1.0': {}
7306
+
7307
+ '@protobufjs/utf8@1.1.0': {}
7308
+
7309
  '@rollup/plugin-babel@5.3.1(@babel/core@7.28.0)(@types/babel__core@7.20.5)(rollup@2.79.2)':
7310
  dependencies:
7311
  '@babel/core': 7.28.0
 
8211
 
8212
  boolbase@1.0.0: {}
8213
 
8214
+ boolean@3.2.0: {}
8215
+
8216
  brace-expansion@1.1.12:
8217
  dependencies:
8218
  balanced-match: 1.0.2
 
8333
  optionalDependencies:
8334
  fsevents: 2.3.3
8335
 
8336
+ chownr@3.0.0: {}
8337
+
8338
  chrome-trace-event@1.0.4: {}
8339
 
8340
  ci-info@3.9.0: {}
 
8383
  color-convert: 1.9.3
8384
  color-string: 1.9.1
8385
 
8386
+ color@4.2.3:
8387
+ dependencies:
8388
+ color-convert: 2.0.1
8389
+ color-string: 1.9.1
8390
+
8391
  colord@2.9.3: {}
8392
 
8393
  colorette@2.0.20: {}
 
8695
 
8696
  destroy@1.2.0: {}
8697
 
8698
+ detect-libc@2.0.4: {}
8699
+
8700
  detect-newline@3.1.0: {}
8701
 
8702
  detect-node@2.1.0: {}
 
8935
  is-date-object: 1.1.0
8936
  is-symbol: 1.1.1
8937
 
8938
+ es6-error@4.1.1: {}
8939
+
8940
  escalade@3.2.0: {}
8941
 
8942
  escape-html@1.0.3: {}
 
9354
  keyv: 4.5.4
9355
  rimraf: 3.0.2
9356
 
9357
+ flatbuffers@25.2.10: {}
9358
+
9359
  flatted@3.3.3: {}
9360
 
9361
  fn.name@1.1.0: {}
 
9499
  once: 1.4.0
9500
  path-is-absolute: 1.0.1
9501
 
9502
+ global-agent@3.0.0:
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
  global-modules@2.0.0:
9512
  dependencies:
9513
  global-prefix: 3.0.0
 
9542
 
9543
  graphemer@1.4.0: {}
9544
 
9545
+ guid-typescript@1.0.9: {}
9546
+
9547
  gzip-size@6.0.0:
9548
  dependencies:
9549
  duplexer: 0.1.2
 
10418
 
10419
  json-stable-stringify-without-jsonify@1.0.1: {}
10420
 
10421
+ json-stringify-safe@5.0.1: {}
10422
+
10423
  json5@1.0.2:
10424
  dependencies:
10425
  minimist: 1.2.8
 
10539
  safe-stable-stringify: 2.5.0
10540
  triple-beam: 1.4.1
10541
 
10542
+ long@5.3.2: {}
10543
+
10544
  loose-envify@1.4.0:
10545
  dependencies:
10546
  js-tokens: 4.0.0
 
10573
  dependencies:
10574
  tmpl: 1.0.5
10575
 
10576
+ matcher@3.0.0:
10577
+ dependencies:
10578
+ escape-string-regexp: 4.0.0
10579
+
10580
  math-intrinsics@1.1.0: {}
10581
 
10582
  mdn-data@2.0.14: {}
 
10640
 
10641
  minipass@7.1.2: {}
10642
 
10643
+ minizlib@3.0.2:
10644
+ dependencies:
10645
+ minipass: 7.1.2
10646
+
10647
  mkdirp@0.5.6:
10648
  dependencies:
10649
  minimist: 1.2.8
10650
 
10651
+ mkdirp@3.0.1: {}
10652
+
10653
  moo-server@1.3.0: {}
10654
 
10655
  ms@2.0.0: {}
 
10784
  dependencies:
10785
  mimic-fn: 2.1.0
10786
 
10787
+ onnxruntime-common@1.21.0: {}
10788
+
10789
+ onnxruntime-common@1.22.0-dev.20250409-89f8206ba4: {}
10790
+
10791
+ onnxruntime-node@1.21.0:
10792
+ dependencies:
10793
+ global-agent: 3.0.0
10794
+ onnxruntime-common: 1.21.0
10795
+ tar: 7.4.3
10796
+
10797
+ onnxruntime-web@1.22.0-dev.20250409-89f8206ba4:
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
  open@8.4.2:
10807
  dependencies:
10808
  define-lazy-prop: 2.0.0
 
10926
  dependencies:
10927
  find-up: 3.0.0
10928
 
10929
+ platform@1.3.6: {}
10930
+
10931
  possible-typed-array-names@1.1.0: {}
10932
 
10933
  postcss-attribute-case-insensitive@5.0.2(postcss@8.5.6):
 
11402
  object-assign: 4.1.1
11403
  react-is: 16.13.1
11404
 
11405
+ protobufjs@7.5.3:
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
  proxy-addr@2.0.7:
11421
  dependencies:
11422
  forwarded: 0.2.0
 
11734
  dependencies:
11735
  glob: 7.2.3
11736
 
11737
+ roarr@2.15.4:
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
  rollup-plugin-terser@7.0.2(rollup@2.79.2):
11747
  dependencies:
11748
  '@babel/code-frame': 7.27.1
 
11834
  '@types/node-forge': 1.3.12
11835
  node-forge: 1.3.1
11836
 
11837
+ semver-compare@1.0.0: {}
11838
+
11839
  semver@6.3.1: {}
11840
 
11841
  semver@7.7.2: {}
 
11858
  transitivePeerDependencies:
11859
  - supports-color
11860
 
11861
+ serialize-error@7.0.1:
11862
+ dependencies:
11863
+ type-fest: 0.13.1
11864
+
11865
  serialize-javascript@4.0.0:
11866
  dependencies:
11867
  randombytes: 2.1.0
 
11917
 
11918
  setprototypeof@1.2.0: {}
11919
 
11920
+ sharp@0.34.2:
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
  shebang-command@2.0.0:
11949
  dependencies:
11950
  shebang-regex: 3.0.0
 
12050
 
12051
  sprintf-js@1.0.3: {}
12052
 
12053
+ sprintf-js@1.1.3: {}
12054
+
12055
  stable@0.1.8: {}
12056
 
12057
  stack-trace@0.0.10: {}
 
12285
 
12286
  tapable@2.2.2: {}
12287
 
12288
+ tar@7.4.3:
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
  temp-dir@2.0.0: {}
12298
 
12299
  tempy@0.6.0:
 
12403
 
12404
  type-detect@4.0.8: {}
12405
 
12406
+ type-fest@0.13.1: {}
12407
+
12408
  type-fest@0.16.0: {}
12409
 
12410
  type-fest@0.20.2: {}
 
12915
 
12916
  yallist@3.1.1: {}
12917
 
12918
+ yallist@5.0.0: {}
12919
+
12920
  yaml@1.10.2: {}
12921
 
12922
  yaml@2.8.0: {}
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
+ });