From cb1b56f5a0eddbf77446f415f2beda57c8305f85 Mon Sep 17 00:00:00 2001 From: polwex Date: Sun, 23 Nov 2025 01:12:53 +0700 Subject: wut --- packages/prosody-ui/src/LangText.tsx | 78 ++++++ packages/prosody-ui/src/Paragraph.tsx | 56 ++++ .../assets/fonts/Hani/BeiShiDaJiaGuWenZiTi-1.ttf | Bin 0 -> 1984156 bytes .../src/assets/fonts/Hani/GaiLiangShouJinTi-2.ttf | Bin 0 -> 4827080 bytes .../src/assets/fonts/Hani/GuDianMingChaoKai-2.ttf | Bin 0 -> 30564660 bytes .../src/assets/fonts/Hani/Iansui-Regular.ttf | Bin 0 -> 9396328 bytes .../assets/fonts/Hani/LiuJianMaoCao-Regular.ttf | Bin 0 -> 4940224 bytes .../src/assets/fonts/Hani/LongCang-Regular.ttf | Bin 0 -> 5151180 bytes .../src/assets/fonts/Hani/Meirenzhuan.ttf | Bin 0 -> 7336648 bytes .../fonts/Hani/No.300-ShangShouGuHuangTi-2.ttf | Bin 0 -> 4890264 bytes .../src/assets/fonts/Hani/NotoSansHK-Black.ttf | Bin 0 -> 7082052 bytes .../src/assets/fonts/Hani/NotoSansHK-Bold.ttf | Bin 0 -> 7088136 bytes .../src/assets/fonts/Hani/NotoSansHK-ExtraBold.ttf | Bin 0 -> 7084512 bytes .../assets/fonts/Hani/NotoSansHK-ExtraLight.ttf | Bin 0 -> 7095176 bytes .../src/assets/fonts/Hani/NotoSansHK-Light.ttf | Bin 0 -> 7095576 bytes .../src/assets/fonts/Hani/NotoSansHK-Medium.ttf | Bin 0 -> 7089444 bytes .../src/assets/fonts/Hani/NotoSansHK-Regular.ttf | Bin 0 -> 7093428 bytes .../src/assets/fonts/Hani/NotoSansHK-SemiBold.ttf | Bin 0 -> 7086788 bytes .../src/assets/fonts/Hani/NotoSansHK-Thin.ttf | Bin 0 -> 7092016 bytes .../fonts/Hani/NotoSansHK-VariableFont_wght.ttf | Bin 0 -> 11909304 bytes .../Hani/YeZiGongChangZuiHanJiangXingCao-2.ttf | Bin 0 -> 5486956 bytes .../src/assets/fonts/Hani/YiShanBeiZhuanTi.ttf | Bin 0 -> 2314256 bytes .../src/assets/fonts/Hani/ZhiMangXing-Regular.ttf | Bin 0 -> 4052388 bytes .../dingliezhuhaifont-20240831GengXinBan)-2.ttf | Bin 0 -> 5359608 bytes .../prosody-ui/src/assets/fonts/Hani/style.css | 223 ++++++++++++++++ ...44\251\351\276\231\350\241\214\346\245\267.ttf" | Bin 0 -> 3344412 bytes .../src/assets/fonts/IPA/Judson-Bold.ttf | Bin 0 -> 192452 bytes .../src/assets/fonts/IPA/Judson-Italic.ttf | Bin 0 -> 209028 bytes .../src/assets/fonts/IPA/Judson-Regular.ttf | Bin 0 -> 217096 bytes .../IPA/NotoSans-Italic-VariableFont_wdth,wght.ttf | Bin 0 -> 2637272 bytes .../fonts/IPA/NotoSans-VariableFont_wdth,wght.ttf | Bin 0 -> 2490816 bytes .../src/assets/fonts/IPA/Voces-Regular.ttf | Bin 0 -> 119992 bytes packages/prosody-ui/src/assets/fonts/IPA/style.css | 33 +++ .../assets/fonts/Jpan/DelaGothicOne-Regular.ttf | Bin 0 -> 2487960 bytes .../src/assets/fonts/Jpan/KaiseiDecol-Bold.ttf | Bin 0 -> 4256124 bytes .../src/assets/fonts/Jpan/KaiseiDecol-Medium.ttf | Bin 0 -> 4265764 bytes .../src/assets/fonts/Jpan/KaiseiDecol-Regular.ttf | Bin 0 -> 4472380 bytes .../assets/fonts/Jpan/ZenAntiqueSoft-Regular.ttf | Bin 0 -> 7095584 bytes .../src/assets/fonts/Jpan/ZenKurenaido-Regular.ttf | Bin 0 -> 4303064 bytes .../prosody-ui/src/assets/fonts/Jpan/style.css | 223 ++++++++++++++++ .../src/assets/fonts/Latn/Poppins/OFL.txt | 93 +++++++ .../assets/fonts/Latn/Poppins/Poppins-Black.ttf | Bin 0 -> 151396 bytes .../fonts/Latn/Poppins/Poppins-BlackItalic.ttf | Bin 0 -> 171604 bytes .../src/assets/fonts/Latn/Poppins/Poppins-Bold.ttf | Bin 0 -> 153944 bytes .../fonts/Latn/Poppins/Poppins-BoldItalic.ttf | Bin 0 -> 176588 bytes .../fonts/Latn/Poppins/Poppins-ExtraBold.ttf | Bin 0 -> 152764 bytes .../fonts/Latn/Poppins/Poppins-ExtraBoldItalic.ttf | Bin 0 -> 173916 bytes .../fonts/Latn/Poppins/Poppins-ExtraLight.ttf | Bin 0 -> 161456 bytes .../Latn/Poppins/Poppins-ExtraLightItalic.ttf | Bin 0 -> 186168 bytes .../assets/fonts/Latn/Poppins/Poppins-Italic.ttf | Bin 0 -> 182012 bytes .../assets/fonts/Latn/Poppins/Poppins-Light.ttf | Bin 0 -> 159892 bytes .../fonts/Latn/Poppins/Poppins-LightItalic.ttf | Bin 0 -> 184460 bytes .../assets/fonts/Latn/Poppins/Poppins-Medium.ttf | Bin 0 -> 156520 bytes .../fonts/Latn/Poppins/Poppins-MediumItalic.ttf | Bin 0 -> 180444 bytes .../assets/fonts/Latn/Poppins/Poppins-Regular.ttf | Bin 0 -> 158240 bytes .../assets/fonts/Latn/Poppins/Poppins-SemiBold.ttf | Bin 0 -> 155232 bytes .../fonts/Latn/Poppins/Poppins-SemiBoldItalic.ttf | Bin 0 -> 178584 bytes .../src/assets/fonts/Latn/Poppins/Poppins-Thin.ttf | Bin 0 -> 161652 bytes .../fonts/Latn/Poppins/Poppins-ThinItalic.ttf | Bin 0 -> 187044 bytes .../prosody-ui/src/assets/fonts/Latn/style.css | 11 + .../src/assets/fonts/Thai/Charm-Bold.ttf | Bin 0 -> 135416 bytes .../src/assets/fonts/Thai/Charm-Regular.ttf | Bin 0 -> 134652 bytes .../src/assets/fonts/Thai/Chonburi-Regular.ttf | Bin 0 -> 168404 bytes .../src/assets/fonts/Thai/IBMPlexSansThai-Bold.ttf | Bin 0 -> 113924 bytes .../fonts/Thai/IBMPlexSansThai-ExtraLight.ttf | Bin 0 -> 117248 bytes .../assets/fonts/Thai/IBMPlexSansThai-Light.ttf | Bin 0 -> 115728 bytes .../assets/fonts/Thai/IBMPlexSansThai-Medium.ttf | Bin 0 -> 113640 bytes .../assets/fonts/Thai/IBMPlexSansThai-Regular.ttf | Bin 0 -> 113392 bytes .../assets/fonts/Thai/IBMPlexSansThai-SemiBold.ttf | Bin 0 -> 113856 bytes .../src/assets/fonts/Thai/IBMPlexSansThai-Thin.ttf | Bin 0 -> 118256 bytes .../src/assets/fonts/Thai/Kanit-Black.ttf | Bin 0 -> 173492 bytes .../src/assets/fonts/Thai/Kanit-BlackItalic.ttf | Bin 0 -> 182076 bytes .../src/assets/fonts/Thai/Kanit-Bold.ttf | Bin 0 -> 172876 bytes .../src/assets/fonts/Thai/Kanit-BoldItalic.ttf | Bin 0 -> 180308 bytes .../src/assets/fonts/Thai/Kanit-ExtraBold.ttf | Bin 0 -> 174464 bytes .../assets/fonts/Thai/Kanit-ExtraBoldItalic.ttf | Bin 0 -> 184928 bytes .../src/assets/fonts/Thai/Kanit-ExtraLight.ttf | Bin 0 -> 160796 bytes .../assets/fonts/Thai/Kanit-ExtraLightItalic.ttf | Bin 0 -> 164908 bytes .../src/assets/fonts/Thai/Kanit-Italic.ttf | Bin 0 -> 171876 bytes .../src/assets/fonts/Thai/Kanit-Light.ttf | Bin 0 -> 168036 bytes .../src/assets/fonts/Thai/Kanit-LightItalic.ttf | Bin 0 -> 171596 bytes .../src/assets/fonts/Thai/Kanit-Medium.ttf | Bin 0 -> 171336 bytes .../src/assets/fonts/Thai/Kanit-MediumItalic.ttf | Bin 0 -> 172360 bytes .../src/assets/fonts/Thai/Kanit-Regular.ttf | Bin 0 -> 169744 bytes .../src/assets/fonts/Thai/Kanit-SemiBold.ttf | Bin 0 -> 171548 bytes .../src/assets/fonts/Thai/Kanit-SemiBoldItalic.ttf | Bin 0 -> 172244 bytes .../src/assets/fonts/Thai/Kanit-Thin.ttf | Bin 0 -> 155788 bytes .../src/assets/fonts/Thai/Kanit-ThinItalic.ttf | Bin 0 -> 161688 bytes .../src/assets/fonts/Thai/Kodchasan-Bold.ttf | Bin 0 -> 98600 bytes .../src/assets/fonts/Thai/Kodchasan-BoldItalic.ttf | Bin 0 -> 104048 bytes .../src/assets/fonts/Thai/Kodchasan-ExtraLight.ttf | Bin 0 -> 96992 bytes .../fonts/Thai/Kodchasan-ExtraLightItalic.ttf | Bin 0 -> 101308 bytes .../src/assets/fonts/Thai/Kodchasan-Italic.ttf | Bin 0 -> 103088 bytes .../src/assets/fonts/Thai/Kodchasan-Light.ttf | Bin 0 -> 98168 bytes .../assets/fonts/Thai/Kodchasan-LightItalic.ttf | Bin 0 -> 102364 bytes .../src/assets/fonts/Thai/Kodchasan-Medium.ttf | Bin 0 -> 98740 bytes .../assets/fonts/Thai/Kodchasan-MediumItalic.ttf | Bin 0 -> 103552 bytes .../src/assets/fonts/Thai/Kodchasan-Regular.ttf | Bin 0 -> 98392 bytes .../src/assets/fonts/Thai/Kodchasan-SemiBold.ttf | Bin 0 -> 98824 bytes .../assets/fonts/Thai/Kodchasan-SemiBoldItalic.ttf | Bin 0 -> 104024 bytes .../prosody-ui/src/assets/fonts/Thai/Mali-Bold.ttf | Bin 0 -> 105372 bytes .../src/assets/fonts/Thai/Mali-BoldItalic.ttf | Bin 0 -> 108796 bytes .../src/assets/fonts/Thai/Mali-ExtraLight.ttf | Bin 0 -> 105668 bytes .../assets/fonts/Thai/Mali-ExtraLightItalic.ttf | Bin 0 -> 108572 bytes .../src/assets/fonts/Thai/Mali-Italic.ttf | Bin 0 -> 108960 bytes .../src/assets/fonts/Thai/Mali-Light.ttf | Bin 0 -> 105864 bytes .../src/assets/fonts/Thai/Mali-LightItalic.ttf | Bin 0 -> 108732 bytes .../src/assets/fonts/Thai/Mali-Medium.ttf | Bin 0 -> 105988 bytes .../src/assets/fonts/Thai/Mali-MediumItalic.ttf | Bin 0 -> 109008 bytes .../src/assets/fonts/Thai/Mali-Regular.ttf | Bin 0 -> 105896 bytes .../src/assets/fonts/Thai/Mali-SemiBold.ttf | Bin 0 -> 106032 bytes .../src/assets/fonts/Thai/Mali-SemiBoldItalic.ttf | Bin 0 -> 109000 bytes .../src/assets/fonts/Thai/Sarabun-Bold.ttf | Bin 0 -> 82592 bytes .../src/assets/fonts/Thai/Sarabun-BoldItalic.ttf | Bin 0 -> 85636 bytes .../src/assets/fonts/Thai/Sarabun-ExtraBold.ttf | Bin 0 -> 82632 bytes .../assets/fonts/Thai/Sarabun-ExtraBoldItalic.ttf | Bin 0 -> 85448 bytes .../src/assets/fonts/Thai/Sarabun-ExtraLight.ttf | Bin 0 -> 83276 bytes .../assets/fonts/Thai/Sarabun-ExtraLightItalic.ttf | Bin 0 -> 86368 bytes .../src/assets/fonts/Thai/Sarabun-Italic.ttf | Bin 0 -> 86024 bytes .../src/assets/fonts/Thai/Sarabun-Light.ttf | Bin 0 -> 83224 bytes .../src/assets/fonts/Thai/Sarabun-LightItalic.ttf | Bin 0 -> 86072 bytes .../src/assets/fonts/Thai/Sarabun-Medium.ttf | Bin 0 -> 83080 bytes .../src/assets/fonts/Thai/Sarabun-MediumItalic.ttf | Bin 0 -> 86136 bytes .../src/assets/fonts/Thai/Sarabun-Regular.ttf | Bin 0 -> 83080 bytes .../src/assets/fonts/Thai/Sarabun-SemiBold.ttf | Bin 0 -> 82952 bytes .../assets/fonts/Thai/Sarabun-SemiBoldItalic.ttf | Bin 0 -> 86020 bytes .../src/assets/fonts/Thai/Sarabun-Thin.ttf | Bin 0 -> 83408 bytes .../src/assets/fonts/Thai/Sarabun-ThinItalic.ttf | Bin 0 -> 86344 bytes .../prosody-ui/src/assets/fonts/Thai/style.css | 76 ++++++ packages/prosody-ui/src/assets/icons/bookmark.svg | 4 + packages/prosody-ui/src/assets/icons/font.svg | 2 + packages/prosody-ui/src/assets/icons/heart.svg | 4 + packages/prosody-ui/src/assets/icons/play.svg | 4 + packages/prosody-ui/src/assets/icons/quote.svg | 28 ++ packages/prosody-ui/src/assets/icons/react.svg | 1 + packages/prosody-ui/src/assets/icons/share.svg | 28 ++ packages/prosody-ui/src/assets/icons/speaker.svg | 32 +++ packages/prosody-ui/src/assets/icons/spinner.svg | 1 + packages/prosody-ui/src/components/Sentence.tsx | 57 +++++ packages/prosody-ui/src/components/Word.tsx | 119 +++++++++ packages/prosody-ui/src/components/sentence.css | 272 ++++++++++++++++++++ packages/prosody-ui/src/components/word.css | 0 packages/prosody-ui/src/files.d.ts | 4 + packages/prosody-ui/src/fonts/FontChanger.tsx | 64 +++++ packages/prosody-ui/src/fonts/Hani.tsx | 14 + packages/prosody-ui/src/fonts/Thai.tsx | 8 + packages/prosody-ui/src/fonts/useLangFont.tsx | 44 ++++ packages/prosody-ui/src/hooks/useLang.tsx | 184 ++++++++++++++ packages/prosody-ui/src/hooks/useModal.tsx | 53 ++++ packages/prosody-ui/src/hooks/useTTS.tsx | 3 + packages/prosody-ui/src/latin/LatinText.tsx | 77 ++++++ packages/prosody-ui/src/logic/iso6393to1.ts | 186 ++++++++++++++ packages/prosody-ui/src/logic/stanza.ts | 86 +++++++ packages/prosody-ui/src/logic/types.ts | 48 ++++ packages/prosody-ui/src/logic/utils.ts | 66 +++++ packages/prosody-ui/src/logic/wiki.ts | 138 ++++++++++ packages/prosody-ui/src/sortug.css | 248 ++++++++++++++++++ packages/prosody-ui/src/styles/styles.css | 281 +++++++++++++++++++++ packages/prosody-ui/src/thai/ThaiText.tsx | 49 ++++ packages/prosody-ui/src/thai/logic/thainlp.ts | 90 +++++++ packages/prosody-ui/src/zoom/FullText.tsx | 60 +++++ packages/prosody-ui/src/zoom/Paragraph.tsx | 60 +++++ packages/prosody-ui/src/zoom/Sentence.tsx | 46 ++++ packages/prosody-ui/src/zoom/SpacyClause.tsx | 125 +++++++++ packages/prosody-ui/src/zoom/animations.ts | 199 +++++++++++++++ packages/prosody-ui/src/zoom/hooks/useZoom.tsx | 135 ++++++++++ packages/prosody-ui/src/zoom/index.ts | 8 + packages/prosody-ui/src/zoom/logic/types.ts | 53 ++++ packages/prosody-ui/src/zoom/spacy.css | 39 +++ 169 files changed, 3713 insertions(+) create mode 100644 packages/prosody-ui/src/LangText.tsx create mode 100644 packages/prosody-ui/src/Paragraph.tsx create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/BeiShiDaJiaGuWenZiTi-1.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/GaiLiangShouJinTi-2.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/GuDianMingChaoKai-2.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/Iansui-Regular.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/LiuJianMaoCao-Regular.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/LongCang-Regular.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/Meirenzhuan.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/No.300-ShangShouGuHuangTi-2.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Black.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Bold.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-ExtraBold.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-ExtraLight.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Light.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Medium.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Regular.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-SemiBold.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Thin.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-VariableFont_wght.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/YeZiGongChangZuiHanJiangXingCao-2.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/YiShanBeiZhuanTi.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/ZhiMangXing-Regular.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/dingliezhuhaifont-20240831GengXinBan)-2.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Hani/style.css create mode 100644 "packages/prosody-ui/src/assets/fonts/Hani/\345\255\227\351\255\202\345\244\251\351\276\231\350\241\214\346\245\267.ttf" create mode 100755 packages/prosody-ui/src/assets/fonts/IPA/Judson-Bold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/IPA/Judson-Italic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/IPA/Judson-Regular.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/IPA/NotoSans-Italic-VariableFont_wdth,wght.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/IPA/NotoSans-VariableFont_wdth,wght.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/IPA/Voces-Regular.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/IPA/style.css create mode 100644 packages/prosody-ui/src/assets/fonts/Jpan/DelaGothicOne-Regular.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Jpan/KaiseiDecol-Bold.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Jpan/KaiseiDecol-Medium.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Jpan/KaiseiDecol-Regular.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Jpan/ZenAntiqueSoft-Regular.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Jpan/ZenKurenaido-Regular.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Jpan/style.css create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/OFL.txt create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Black.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-BlackItalic.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Bold.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-BoldItalic.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraBold.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraBoldItalic.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraLight.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraLightItalic.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Italic.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Light.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-LightItalic.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Medium.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-MediumItalic.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Regular.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-SemiBold.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-SemiBoldItalic.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Thin.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ThinItalic.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Latn/style.css create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Charm-Bold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Charm-Regular.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Chonburi-Regular.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Bold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-ExtraLight.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Light.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Medium.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Regular.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-SemiBold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Thin.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-Black.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-BlackItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-Bold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-BoldItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraBold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraBoldItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraLight.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraLightItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-Italic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-Light.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-LightItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-Medium.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-MediumItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-Regular.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-SemiBold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-SemiBoldItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-Thin.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kanit-ThinItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Bold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-BoldItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-ExtraLight.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-ExtraLightItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Italic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Light.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-LightItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Medium.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-MediumItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Regular.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-SemiBold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-SemiBoldItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Mali-Bold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Mali-BoldItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Mali-ExtraLight.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Mali-ExtraLightItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Mali-Italic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Mali-Light.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Mali-LightItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Mali-Medium.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Mali-MediumItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Mali-Regular.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Mali-SemiBold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Mali-SemiBoldItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Bold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-BoldItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraBold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraBoldItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraLight.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraLightItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Italic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Light.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-LightItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Medium.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-MediumItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Regular.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-SemiBold.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-SemiBoldItalic.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Thin.ttf create mode 100755 packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ThinItalic.ttf create mode 100644 packages/prosody-ui/src/assets/fonts/Thai/style.css create mode 100755 packages/prosody-ui/src/assets/icons/bookmark.svg create mode 100755 packages/prosody-ui/src/assets/icons/font.svg create mode 100755 packages/prosody-ui/src/assets/icons/heart.svg create mode 100755 packages/prosody-ui/src/assets/icons/play.svg create mode 100755 packages/prosody-ui/src/assets/icons/quote.svg create mode 100755 packages/prosody-ui/src/assets/icons/react.svg create mode 100755 packages/prosody-ui/src/assets/icons/share.svg create mode 100644 packages/prosody-ui/src/assets/icons/speaker.svg create mode 100755 packages/prosody-ui/src/assets/icons/spinner.svg create mode 100644 packages/prosody-ui/src/components/Sentence.tsx create mode 100644 packages/prosody-ui/src/components/Word.tsx create mode 100644 packages/prosody-ui/src/components/sentence.css create mode 100644 packages/prosody-ui/src/components/word.css create mode 100644 packages/prosody-ui/src/files.d.ts create mode 100644 packages/prosody-ui/src/fonts/FontChanger.tsx create mode 100644 packages/prosody-ui/src/fonts/Hani.tsx create mode 100644 packages/prosody-ui/src/fonts/Thai.tsx create mode 100644 packages/prosody-ui/src/fonts/useLangFont.tsx create mode 100644 packages/prosody-ui/src/hooks/useLang.tsx create mode 100644 packages/prosody-ui/src/hooks/useModal.tsx create mode 100644 packages/prosody-ui/src/hooks/useTTS.tsx create mode 100644 packages/prosody-ui/src/latin/LatinText.tsx create mode 100644 packages/prosody-ui/src/logic/iso6393to1.ts create mode 100644 packages/prosody-ui/src/logic/stanza.ts create mode 100644 packages/prosody-ui/src/logic/types.ts create mode 100644 packages/prosody-ui/src/logic/utils.ts create mode 100644 packages/prosody-ui/src/logic/wiki.ts create mode 100644 packages/prosody-ui/src/sortug.css create mode 100644 packages/prosody-ui/src/styles/styles.css create mode 100644 packages/prosody-ui/src/thai/ThaiText.tsx create mode 100644 packages/prosody-ui/src/thai/logic/thainlp.ts create mode 100644 packages/prosody-ui/src/zoom/FullText.tsx create mode 100644 packages/prosody-ui/src/zoom/Paragraph.tsx create mode 100644 packages/prosody-ui/src/zoom/Sentence.tsx create mode 100644 packages/prosody-ui/src/zoom/SpacyClause.tsx create mode 100644 packages/prosody-ui/src/zoom/animations.ts create mode 100644 packages/prosody-ui/src/zoom/hooks/useZoom.tsx create mode 100644 packages/prosody-ui/src/zoom/index.ts create mode 100644 packages/prosody-ui/src/zoom/logic/types.ts create mode 100644 packages/prosody-ui/src/zoom/spacy.css (limited to 'packages/prosody-ui/src') diff --git a/packages/prosody-ui/src/LangText.tsx b/packages/prosody-ui/src/LangText.tsx new file mode 100644 index 0000000..790c499 --- /dev/null +++ b/packages/prosody-ui/src/LangText.tsx @@ -0,0 +1,78 @@ +import { franc } from "franc-all"; +import React, { useEffect, useState } from "react"; +import ThaiText from "./thai/ThaiText"; +import { ColoredText } from "./components/Sentence"; +import type { AnalyzeRes, WordData } from "./logic/types"; +import { detectScript, scriptFromLang } from "./logic/utils"; +import LatinText from "./latin/LatinText"; +import { buildWiktionaryURL, parseWiktionary } from "./logic/wiki"; +import type { Result } from "sortug"; + +export default function LangText({ + text, + lang, + theme, + fetchWiki, + handleWord, +}: { + text: string; + lang?: string; + theme?: string; + fetchWiki?: (url: string) => Promise; + handleWord?: (wd: Result) => any; +}) { + const [llang, setLang] = useState(""); + const [script, setScript] = useState(scriptFromLang(lang || "", text)); + useEffect(() => { + if (!lang) { + const res = franc(text); + setLang(res); + } else setLang(lang); + }, [text]); + console.log("langtext", { text, llang, script }); + + async function openWord(word: string) { + // console.log("looking up", word); + // const url = buildWiktionaryURL(word); + // const html = await fetchWiki(url); + // const parsed = parseWiktionary(html, url); + // console.log({ parsed }); + // if ("error" in parsed) handleWord(parsed); + // else { + // const wd: WordData = { + // spelling: word, + // lang: llang, + // ipa: parsed.ok.ipa[0], + // meanings: parsed.ok.meanings, + // references: { url: parsed.ok.url }, + // }; + // handleWord({ ok: wd }); + // } + // // const d = data[s]; + // // setModal(d); + // // setModal(); + } + + return ( +
+ {script === "Thai" ? ( + + ) : script === "Latin" ? ( + + ) : ( + + )} +
+ ); +} +function Generic({ text, lang }: { text: string; lang: string }) { + const [data, setData] = useState(); + useEffect(() => { + // segmentate(text, lang) + }, [text, lang]); + console.log({ lang }, "generic"); + //

{lang}

+ //

{text}

+ // {data && } + return
; +} diff --git a/packages/prosody-ui/src/Paragraph.tsx b/packages/prosody-ui/src/Paragraph.tsx new file mode 100644 index 0000000..72c43a7 --- /dev/null +++ b/packages/prosody-ui/src/Paragraph.tsx @@ -0,0 +1,56 @@ +import { franc } from "franc-all"; +import React, { useCallback, useEffect, useState } from "react"; +import ThaiText from "./thai/ThaiText"; +import { ColoredText } from "./components/Sentence"; +import type { AnalyzeRes, WordData } from "./logic/types"; +import { detectScript, langFromScript } from "./logic/utils"; +import LatinText from "./latin/LatinText"; +import { buildWiktionaryURL, parseWiktionary } from "./logic/wiki"; +import type { Result } from "sortug"; +import * as Stanza from "./logic/stanza"; +import { iso6393To1 } from "./logic/iso6393to1"; + +export default function Paragraph({ + text, +}: { + text: string; + handleWord?: (wd: Result) => any; +}) { + useEffect(() => { + segmentString(); + }, [text]); + const [lang, setLang] = useState(""); + const [script, setScript] = useState(""); + const [segs, setSegs] = useState([]); + useEffect(() => { + const res = franc(text); + console.log(); + console.log({ res, text }); + if (res === "und") detectLanguage(); + else { + const smol = iso6393To1[res]; + if (!smol) console.log("lang", res); + else setLang(smol); + } + }, [text]); + + const segmentString = useCallback(async () => { + if (lang) { + const res = await Stanza.segmenter(text, lang); + if ("ok" in res) setSegs(res.ok.segments); + console.log("stanza", res); + } + }, [text, lang]); + const detectLanguage = useCallback(async () => { + const script = detectScript(text); + if ("error" in script) console.log("ded"); + else { + setScript(script.ok); + const lng = langFromScript(script.ok); + if ("error" in lng) console.log("ded again!"); + else setLang(lng.ok); + } + }, [text]); + + return
{text}
; +} diff --git a/packages/prosody-ui/src/assets/fonts/Hani/BeiShiDaJiaGuWenZiTi-1.ttf b/packages/prosody-ui/src/assets/fonts/Hani/BeiShiDaJiaGuWenZiTi-1.ttf new file mode 100644 index 0000000..5ada19c Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/BeiShiDaJiaGuWenZiTi-1.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/GaiLiangShouJinTi-2.ttf b/packages/prosody-ui/src/assets/fonts/Hani/GaiLiangShouJinTi-2.ttf new file mode 100644 index 0000000..2606d1c Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/GaiLiangShouJinTi-2.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/GuDianMingChaoKai-2.ttf b/packages/prosody-ui/src/assets/fonts/Hani/GuDianMingChaoKai-2.ttf new file mode 100644 index 0000000..49f5405 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/GuDianMingChaoKai-2.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/Iansui-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Hani/Iansui-Regular.ttf new file mode 100644 index 0000000..5da538b Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/Iansui-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/LiuJianMaoCao-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Hani/LiuJianMaoCao-Regular.ttf new file mode 100644 index 0000000..4b7e9bc Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/LiuJianMaoCao-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/LongCang-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Hani/LongCang-Regular.ttf new file mode 100644 index 0000000..44f6a9f Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/LongCang-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/Meirenzhuan.ttf b/packages/prosody-ui/src/assets/fonts/Hani/Meirenzhuan.ttf new file mode 100644 index 0000000..8eb1209 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/Meirenzhuan.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/No.300-ShangShouGuHuangTi-2.ttf b/packages/prosody-ui/src/assets/fonts/Hani/No.300-ShangShouGuHuangTi-2.ttf new file mode 100644 index 0000000..1f16ba8 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/No.300-ShangShouGuHuangTi-2.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Black.ttf b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Black.ttf new file mode 100644 index 0000000..e86fb96 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Black.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Bold.ttf b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Bold.ttf new file mode 100644 index 0000000..76812d7 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Bold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-ExtraBold.ttf b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-ExtraBold.ttf new file mode 100644 index 0000000..db381ed Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-ExtraBold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-ExtraLight.ttf b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-ExtraLight.ttf new file mode 100644 index 0000000..e30cdd8 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-ExtraLight.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Light.ttf b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Light.ttf new file mode 100644 index 0000000..8be49fc Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Light.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Medium.ttf b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Medium.ttf new file mode 100644 index 0000000..f45d4ec Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Medium.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Regular.ttf new file mode 100644 index 0000000..2a62b97 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-SemiBold.ttf b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-SemiBold.ttf new file mode 100644 index 0000000..bc3e266 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-SemiBold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Thin.ttf b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Thin.ttf new file mode 100644 index 0000000..832c29f Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-Thin.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-VariableFont_wght.ttf b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-VariableFont_wght.ttf new file mode 100644 index 0000000..47f2c84 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/NotoSansHK-VariableFont_wght.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/YeZiGongChangZuiHanJiangXingCao-2.ttf b/packages/prosody-ui/src/assets/fonts/Hani/YeZiGongChangZuiHanJiangXingCao-2.ttf new file mode 100644 index 0000000..b59a399 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/YeZiGongChangZuiHanJiangXingCao-2.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/YiShanBeiZhuanTi.ttf b/packages/prosody-ui/src/assets/fonts/Hani/YiShanBeiZhuanTi.ttf new file mode 100644 index 0000000..9364f2d Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/YiShanBeiZhuanTi.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/ZhiMangXing-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Hani/ZhiMangXing-Regular.ttf new file mode 100644 index 0000000..e2d4fad Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/ZhiMangXing-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/dingliezhuhaifont-20240831GengXinBan)-2.ttf b/packages/prosody-ui/src/assets/fonts/Hani/dingliezhuhaifont-20240831GengXinBan)-2.ttf new file mode 100644 index 0000000..b387fc5 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Hani/dingliezhuhaifont-20240831GengXinBan)-2.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Hani/style.css b/packages/prosody-ui/src/assets/fonts/Hani/style.css new file mode 100644 index 0000000..2048617 --- /dev/null +++ b/packages/prosody-ui/src/assets/fonts/Hani/style.css @@ -0,0 +1,223 @@ +/* https://www.fonts.net.cn/fonts-zh/tag-yankai-1.html */ + + +@font-face { + font-family: "BeiShiDaJiaGuWen"; + src: url(./BeiShiDaJiaGuWenZiTi-1.ttf); + font-weight: 300; + font-style: normal +} + +@font-face { + font-family: "ShanShouGuHuangTi"; + src: url(./No.300-ShangShouGuHuangTi-2.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "DinglieZhuhai"; + src: url(./dingliezhuhaifont-20240831GengXinBan-2.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "ShouJin"; + src: url(./GaiLiangShouJinTi-2.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "GudianMingChaoKai"; + src: url(./GuDianMingChaoKai-2.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(./NotoSansHK-SemiBold.ttf); + font-weight: 500; + font-style: normal; +} + + +@font-face { + font-family: "NotoSansHK"; + src: url(./NotoSansHK-Black.ttf); + font-weight: 900; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(./NotoSansHK-Thin.ttf); + font-weight: 200; + font-style: normal; +} + + +@font-face { + font-family: "NotoSansHK"; + src: url(./NotoSansHK-Bold.ttf); + font-weight: 400; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(./NotoSansHK-VariableFont_wght.ttf); + font-weight: 300; + font-style: normal; +} + + +@font-face { + font-family: "NotoSansHK"; + src: url(./NotoSansHK-ExtraBold.ttf); + font-weight: 800; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(./NotoSansHK-ExtraLight.ttf); + font-weight: 100; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(./NotoSansHK-Light.ttf); + font-weight: 200; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(./NotoSansHK-Regular.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(./NotoSansHK-Medium.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "Iansui"; + src: url(./Iansui-Regular.ttf); + font-weight: 300; + font-style: normal; +} + + +@font-face { + font-family: "YeZiGongXingCao"; + src: url(./YeZiGongChangZuiHanJiangXingCao-2.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "LiuJianMaoCao"; + src: url(./LiuJianMaoCao-Regular.ttf); + font-weight: 300; + font-style: normal; +} + + +@font-face { + font-family: "YiShanBeiZhuanti"; + src: url(./YiShanBeiZhuanTi.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "LongCang"; + src: url(./LongCang-Regular.ttf); + font-weight: 300; + font-style: normal; +} + + +@font-face { + font-family: "ZhiMangXing"; + src: url(./ZhiMangXing-Regular.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "Meirenzhuan"; + src: url(./Meirenzhuan.ttf); + font-weight: 300; + font-style: normal; +} + + +@font-face { + font-family: "TianlongXingkai"; + src: url(./字魂天龙行楷.ttf); + font-weight: 300; + font-style: normal; +} + + +.font-Hani-0 { + font-family: "ShouJin"; +} + +.font-Hani-1 { + font-family: "DinglieZhuhai"; +} + +.font-Hani-2 { + font-family: "GudianMingChaokai"; +} + +.font-Hani-3 { + font-family: "NotoSansHK"; +} + +.font-Hani-4 { + font-family: "ShanShouGuHuangTi"; +} + +.font-Hani-5 { + font-family: "Iansui"; +} + +.font-Hani-6 { + font-family: "YeZiGongXingCao"; +} + +.font-Hani-7 { + font-family: "LiuJianMaoCao"; +} + +.font-Hani-8 { + font-family: "YiShanBeiZhuanti"; +} + +.font-Hani-9 { + font-family: "LongCang"; +} + +.font-Hani-10 { + font-family: "ZhiMangXing"; +} + +.font-Hani-11 { + font-family: "Meirenzhuan"; +} + +.font-Hani-12 { + font-family: "TianlongXingkai"; +} \ No newline at end of file diff --git "a/packages/prosody-ui/src/assets/fonts/Hani/\345\255\227\351\255\202\345\244\251\351\276\231\350\241\214\346\245\267.ttf" "b/packages/prosody-ui/src/assets/fonts/Hani/\345\255\227\351\255\202\345\244\251\351\276\231\350\241\214\346\245\267.ttf" new file mode 100644 index 0000000..b565e37 Binary files /dev/null and "b/packages/prosody-ui/src/assets/fonts/Hani/\345\255\227\351\255\202\345\244\251\351\276\231\350\241\214\346\245\267.ttf" differ diff --git a/packages/prosody-ui/src/assets/fonts/IPA/Judson-Bold.ttf b/packages/prosody-ui/src/assets/fonts/IPA/Judson-Bold.ttf new file mode 100755 index 0000000..4b977b0 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/IPA/Judson-Bold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/IPA/Judson-Italic.ttf b/packages/prosody-ui/src/assets/fonts/IPA/Judson-Italic.ttf new file mode 100755 index 0000000..b2ea190 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/IPA/Judson-Italic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/IPA/Judson-Regular.ttf b/packages/prosody-ui/src/assets/fonts/IPA/Judson-Regular.ttf new file mode 100755 index 0000000..a1cbb58 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/IPA/Judson-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/IPA/NotoSans-Italic-VariableFont_wdth,wght.ttf b/packages/prosody-ui/src/assets/fonts/IPA/NotoSans-Italic-VariableFont_wdth,wght.ttf new file mode 100755 index 0000000..4e962ee Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/IPA/NotoSans-Italic-VariableFont_wdth,wght.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/IPA/NotoSans-VariableFont_wdth,wght.ttf b/packages/prosody-ui/src/assets/fonts/IPA/NotoSans-VariableFont_wdth,wght.ttf new file mode 100755 index 0000000..f7d0d78 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/IPA/NotoSans-VariableFont_wdth,wght.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/IPA/Voces-Regular.ttf b/packages/prosody-ui/src/assets/fonts/IPA/Voces-Regular.ttf new file mode 100755 index 0000000..36aa975 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/IPA/Voces-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/IPA/style.css b/packages/prosody-ui/src/assets/fonts/IPA/style.css new file mode 100644 index 0000000..ecc0a8a --- /dev/null +++ b/packages/prosody-ui/src/assets/fonts/IPA/style.css @@ -0,0 +1,33 @@ +@font-face { + font-family: "Voces"; + src: url(./Voces-Regular.ttf); + font-weight: 300; + font-style: normal +} + +@font-face { + font-family: "Judson"; + src: url(./Judson-Regular.ttf); + font-weight: 300; + font-style: normal +} + +/* TODO check the specifics of variable fonts */ +@font-face { + font-family: "Noto Sans"; + src: url(./NotoSans-VariableFont_wdth,wght.ttf); + font-weight: 300; + font-style: normal +} + +.font-IPA-0 { + font-family: "Voces"; +} + +.font-IPA-1 { + font-family: "Judson"; +} + +.font-IPA-2 { + font-family: "Noto Sans"; +} \ No newline at end of file diff --git a/packages/prosody-ui/src/assets/fonts/Jpan/DelaGothicOne-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Jpan/DelaGothicOne-Regular.ttf new file mode 100644 index 0000000..475c4dd Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Jpan/DelaGothicOne-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Jpan/KaiseiDecol-Bold.ttf b/packages/prosody-ui/src/assets/fonts/Jpan/KaiseiDecol-Bold.ttf new file mode 100644 index 0000000..7d13d05 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Jpan/KaiseiDecol-Bold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Jpan/KaiseiDecol-Medium.ttf b/packages/prosody-ui/src/assets/fonts/Jpan/KaiseiDecol-Medium.ttf new file mode 100644 index 0000000..1e35712 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Jpan/KaiseiDecol-Medium.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Jpan/KaiseiDecol-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Jpan/KaiseiDecol-Regular.ttf new file mode 100644 index 0000000..7d68508 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Jpan/KaiseiDecol-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Jpan/ZenAntiqueSoft-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Jpan/ZenAntiqueSoft-Regular.ttf new file mode 100644 index 0000000..c78f7d6 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Jpan/ZenAntiqueSoft-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Jpan/ZenKurenaido-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Jpan/ZenKurenaido-Regular.ttf new file mode 100644 index 0000000..cb3044e Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Jpan/ZenKurenaido-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Jpan/style.css b/packages/prosody-ui/src/assets/fonts/Jpan/style.css new file mode 100644 index 0000000..cd1b79f --- /dev/null +++ b/packages/prosody-ui/src/assets/fonts/Jpan/style.css @@ -0,0 +1,223 @@ +/* https://www.fonts.net.cn/fonts-zh/tag-yankai-1.html */ + + +@font-face { + font-family: "BeiShiDaJiaGuWen"; + src: url(../Hani/BeiShiDaJiaGuWenZiTi-1.ttf); + font-weight: 300; + font-style: normal +} + +@font-face { + font-family: "ShanShouGuHuangTi"; + src: url(../Hani/No.300-ShangShouGuHuangTi-2.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "DinglieZhuhai"; + src: url(../Hani/dingliezhuhaifont-20240831GengXinBan-2.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "ShouJin"; + src: url(../Hani/GaiLiangShouJinTi-2.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "GudianMingChaoKai"; + src: url(../Hani/GuDianMingChaoKai-2.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(../Hani/NotoSansHK-SemiBold.ttf); + font-weight: 500; + font-style: normal; +} + + +@font-face { + font-family: "NotoSansHK"; + src: url(../Hani/NotoSansHK-Black.ttf); + font-weight: 900; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(../Hani/NotoSansHK-Thin.ttf); + font-weight: 200; + font-style: normal; +} + + +@font-face { + font-family: "NotoSansHK"; + src: url(../Hani/NotoSansHK-Bold.ttf); + font-weight: 400; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(../Hani/NotoSansHK-VariableFont_wght.ttf); + font-weight: 300; + font-style: normal; +} + + +@font-face { + font-family: "NotoSansHK"; + src: url(../Hani/NotoSansHK-ExtraBold.ttf); + font-weight: 800; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(../Hani/NotoSansHK-ExtraLight.ttf); + font-weight: 100; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(../Hani/NotoSansHK-Light.ttf); + font-weight: 200; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(../Hani/NotoSansHK-Regular.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "NotoSansHK"; + src: url(../Hani/NotoSansHK-Medium.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "Iansui"; + src: url(../Hani/Iansui-Regular.ttf); + font-weight: 300; + font-style: normal; +} + + +@font-face { + font-family: "YeZiGongXingCao"; + src: url(../Hani/YeZiGongChangZuiHanJiangXingCao-2.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "LiuJianMaoCao"; + src: url(../Hani/LiuJianMaoCao-Regular.ttf); + font-weight: 300; + font-style: normal; +} + + +@font-face { + font-family: "YiShanBeiZhuanti"; + src: url(../Hani/YiShanBeiZhuanTi.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "LongCang"; + src: url(../Hani/LongCang-Regular.ttf); + font-weight: 300; + font-style: normal; +} + + +@font-face { + font-family: "ZhiMangXing"; + src: url(../Hani/ZhiMangXing-Regular.ttf); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "Meirenzhuan"; + src: url(../Hani/Meirenzhuan.ttf); + font-weight: 300; + font-style: normal; +} + + +@font-face { + font-family: "TianlongXingkai"; + src: url(../Hani/字魂天龙行楷.ttf); + font-weight: 300; + font-style: normal; +} + + +.font-Hani-0 { + font-family: "ShouJin"; +} + +.font-Hani-1 { + font-family: "DinglieZhuhai"; +} + +.font-Hani-2 { + font-family: "GudianMingChaokai"; +} + +.font-Hani-3 { + font-family: "NotoSansHK"; +} + +.font-Hani-4 { + font-family: "ShanShouGuHuangTi"; +} + +.font-Hani-5 { + font-family: "Iansui"; +} + +.font-Hani-6 { + font-family: "YeZiGongXingCao"; +} + +.font-Hani-7 { + font-family: "LiuJianMaoCao"; +} + +.font-Hani-8 { + font-family: "YiShanBeiZhuanti"; +} + +.font-Hani-9 { + font-family: "LongCang"; +} + +.font-Hani-10 { + font-family: "ZhiMangXing"; +} + +.font-Hani-11 { + font-family: "Meirenzhuan"; +} + +.font-Hani-12 { + font-family: "TianlongXingkai"; +} \ No newline at end of file diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/OFL.txt b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/OFL.txt new file mode 100644 index 0000000..3e92931 --- /dev/null +++ b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2020 The Poppins Project Authors (https://github.com/itfoundry/Poppins) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Black.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Black.ttf new file mode 100644 index 0000000..71c0f99 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Black.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-BlackItalic.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-BlackItalic.ttf new file mode 100644 index 0000000..7aeb58b Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-BlackItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Bold.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Bold.ttf new file mode 100644 index 0000000..00559ee Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Bold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-BoldItalic.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-BoldItalic.ttf new file mode 100644 index 0000000..e61e8e8 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-BoldItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraBold.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraBold.ttf new file mode 100644 index 0000000..df70936 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraBold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraBoldItalic.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraBoldItalic.ttf new file mode 100644 index 0000000..14d2b37 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraBoldItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraLight.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraLight.ttf new file mode 100644 index 0000000..e76ec69 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraLight.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraLightItalic.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraLightItalic.ttf new file mode 100644 index 0000000..89513d9 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ExtraLightItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Italic.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Italic.ttf new file mode 100644 index 0000000..12b7b3c Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Italic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Light.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Light.ttf new file mode 100644 index 0000000..bc36bcc Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Light.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-LightItalic.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-LightItalic.ttf new file mode 100644 index 0000000..9e70be6 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-LightItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Medium.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Medium.ttf new file mode 100644 index 0000000..6bcdcc2 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Medium.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-MediumItalic.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-MediumItalic.ttf new file mode 100644 index 0000000..be67410 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-MediumItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Regular.ttf new file mode 100644 index 0000000..9f0c71b Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-SemiBold.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-SemiBold.ttf new file mode 100644 index 0000000..74c726e Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-SemiBold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-SemiBoldItalic.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-SemiBoldItalic.ttf new file mode 100644 index 0000000..3e6c942 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-SemiBoldItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Thin.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Thin.ttf new file mode 100644 index 0000000..03e7366 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-Thin.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ThinItalic.ttf b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ThinItalic.ttf new file mode 100644 index 0000000..e26db5d Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Latn/Poppins/Poppins-ThinItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Latn/style.css b/packages/prosody-ui/src/assets/fonts/Latn/style.css new file mode 100644 index 0000000..e2aef9b --- /dev/null +++ b/packages/prosody-ui/src/assets/fonts/Latn/style.css @@ -0,0 +1,11 @@ +@font-face { + font-family: "Poppins"; + src: url(./Poppins.ttf); + font-weight: 300; + font-style: normal; +} + + +.font-Latn-0 { + font-family: "Poppins"; +} \ No newline at end of file diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Charm-Bold.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Charm-Bold.ttf new file mode 100755 index 0000000..d32f072 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Charm-Bold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Charm-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Charm-Regular.ttf new file mode 100755 index 0000000..02013a4 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Charm-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Chonburi-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Chonburi-Regular.ttf new file mode 100755 index 0000000..52fedc7 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Chonburi-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Bold.ttf b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Bold.ttf new file mode 100755 index 0000000..3a8583f Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Bold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-ExtraLight.ttf b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-ExtraLight.ttf new file mode 100755 index 0000000..c4161bd Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-ExtraLight.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Light.ttf b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Light.ttf new file mode 100755 index 0000000..a676550 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Light.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Medium.ttf b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Medium.ttf new file mode 100755 index 0000000..75e62df Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Medium.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Regular.ttf new file mode 100755 index 0000000..c31b8c2 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-SemiBold.ttf b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-SemiBold.ttf new file mode 100755 index 0000000..9812b5a Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-SemiBold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Thin.ttf b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Thin.ttf new file mode 100755 index 0000000..2cc968f Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/IBMPlexSansThai-Thin.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Black.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Black.ttf new file mode 100755 index 0000000..2e37a00 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Black.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-BlackItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-BlackItalic.ttf new file mode 100755 index 0000000..dc81853 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-BlackItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Bold.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Bold.ttf new file mode 100755 index 0000000..4686906 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Bold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-BoldItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-BoldItalic.ttf new file mode 100755 index 0000000..17eda2a Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-BoldItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraBold.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraBold.ttf new file mode 100755 index 0000000..5240d38 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraBold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraBoldItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraBoldItalic.ttf new file mode 100755 index 0000000..037187a Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraBoldItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraLight.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraLight.ttf new file mode 100755 index 0000000..404c1e0 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraLight.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraLightItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraLightItalic.ttf new file mode 100755 index 0000000..5d575cc Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ExtraLightItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Italic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Italic.ttf new file mode 100755 index 0000000..e6d868b Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Italic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Light.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Light.ttf new file mode 100755 index 0000000..3c9d4b5 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Light.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-LightItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-LightItalic.ttf new file mode 100755 index 0000000..59a3f2e Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-LightItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Medium.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Medium.ttf new file mode 100755 index 0000000..50413d0 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Medium.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-MediumItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-MediumItalic.ttf new file mode 100755 index 0000000..2c6aa14 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-MediumItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Regular.ttf new file mode 100755 index 0000000..ef204c1 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-SemiBold.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-SemiBold.ttf new file mode 100755 index 0000000..7501a2e Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-SemiBold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-SemiBoldItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-SemiBoldItalic.ttf new file mode 100755 index 0000000..2284650 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-SemiBoldItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Thin.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Thin.ttf new file mode 100755 index 0000000..5c835ad Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-Thin.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ThinItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ThinItalic.ttf new file mode 100755 index 0000000..25fd1f9 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kanit-ThinItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Bold.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Bold.ttf new file mode 100755 index 0000000..cd36ffc Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Bold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-BoldItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-BoldItalic.ttf new file mode 100755 index 0000000..f86a715 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-BoldItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-ExtraLight.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-ExtraLight.ttf new file mode 100755 index 0000000..af416d2 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-ExtraLight.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-ExtraLightItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-ExtraLightItalic.ttf new file mode 100755 index 0000000..3478406 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-ExtraLightItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Italic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Italic.ttf new file mode 100755 index 0000000..3032d77 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Italic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Light.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Light.ttf new file mode 100755 index 0000000..b3db128 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Light.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-LightItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-LightItalic.ttf new file mode 100755 index 0000000..5acfdd5 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-LightItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Medium.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Medium.ttf new file mode 100755 index 0000000..de8f843 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Medium.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-MediumItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-MediumItalic.ttf new file mode 100755 index 0000000..2c0cb1e Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-MediumItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Regular.ttf new file mode 100755 index 0000000..b6cb5d5 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-SemiBold.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-SemiBold.ttf new file mode 100755 index 0000000..917a988 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-SemiBold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-SemiBoldItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-SemiBoldItalic.ttf new file mode 100755 index 0000000..36d3579 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Kodchasan-SemiBoldItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Mali-Bold.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Mali-Bold.ttf new file mode 100755 index 0000000..db8c190 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Mali-Bold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Mali-BoldItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Mali-BoldItalic.ttf new file mode 100755 index 0000000..a67a0ae Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Mali-BoldItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Mali-ExtraLight.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Mali-ExtraLight.ttf new file mode 100755 index 0000000..0e3f955 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Mali-ExtraLight.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Mali-ExtraLightItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Mali-ExtraLightItalic.ttf new file mode 100755 index 0000000..6f4d3d3 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Mali-ExtraLightItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Mali-Italic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Mali-Italic.ttf new file mode 100755 index 0000000..479a8e8 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Mali-Italic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Mali-Light.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Mali-Light.ttf new file mode 100755 index 0000000..aaad3b6 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Mali-Light.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Mali-LightItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Mali-LightItalic.ttf new file mode 100755 index 0000000..cdfa5c6 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Mali-LightItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Mali-Medium.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Mali-Medium.ttf new file mode 100755 index 0000000..658a6a1 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Mali-Medium.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Mali-MediumItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Mali-MediumItalic.ttf new file mode 100755 index 0000000..4b88574 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Mali-MediumItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Mali-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Mali-Regular.ttf new file mode 100755 index 0000000..70cd35b Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Mali-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Mali-SemiBold.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Mali-SemiBold.ttf new file mode 100755 index 0000000..acdce49 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Mali-SemiBold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Mali-SemiBoldItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Mali-SemiBoldItalic.ttf new file mode 100755 index 0000000..fc76e74 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Mali-SemiBoldItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Bold.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Bold.ttf new file mode 100755 index 0000000..4d6bf36 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Bold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-BoldItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-BoldItalic.ttf new file mode 100755 index 0000000..42857a5 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-BoldItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraBold.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraBold.ttf new file mode 100755 index 0000000..27ba997 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraBold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraBoldItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraBoldItalic.ttf new file mode 100755 index 0000000..bc36f97 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraBoldItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraLight.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraLight.ttf new file mode 100755 index 0000000..060c6c1 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraLight.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraLightItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraLightItalic.ttf new file mode 100755 index 0000000..beaa024 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ExtraLightItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Italic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Italic.ttf new file mode 100755 index 0000000..51d6dbe Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Italic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Light.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Light.ttf new file mode 100755 index 0000000..d2f2291 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Light.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-LightItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-LightItalic.ttf new file mode 100755 index 0000000..75eb8d8 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-LightItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Medium.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Medium.ttf new file mode 100755 index 0000000..e03148e Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Medium.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-MediumItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-MediumItalic.ttf new file mode 100755 index 0000000..b172a09 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-MediumItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Regular.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Regular.ttf new file mode 100755 index 0000000..50fa707 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Regular.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-SemiBold.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-SemiBold.ttf new file mode 100755 index 0000000..7b760ce Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-SemiBold.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-SemiBoldItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-SemiBoldItalic.ttf new file mode 100755 index 0000000..ecc5fb6 Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-SemiBoldItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Thin.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Thin.ttf new file mode 100755 index 0000000..cdaabcb Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-Thin.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ThinItalic.ttf b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ThinItalic.ttf new file mode 100755 index 0000000..e96d17e Binary files /dev/null and b/packages/prosody-ui/src/assets/fonts/Thai/Sarabun-ThinItalic.ttf differ diff --git a/packages/prosody-ui/src/assets/fonts/Thai/style.css b/packages/prosody-ui/src/assets/fonts/Thai/style.css new file mode 100644 index 0000000..14b828c --- /dev/null +++ b/packages/prosody-ui/src/assets/fonts/Thai/style.css @@ -0,0 +1,76 @@ +@font-face { + font-family: "Kanit"; + src: url(./Kanit-Regular.ttf); +} + +@font-face { + font-family: "Sarabun"; + src: url(./Sarabun-Regular.ttf); + font-weight: 300; + font-style: normal +} + +@font-face { + font-family: "IBM Plex Sans Thai"; + src: url(./IBMPlexSansThai-Regular.ttf); + font-weight: 300; + font-style: normal +} + +@font-face { + font-family: "Mali"; + src: url(./Mali-Regular.ttf); + font-weight: 300; + font-style: normal +} + +@font-face { + font-family: "Kodchasan"; + src: url(./Kodchasan-Regular.ttf); + font-weight: 300; + font-style: normal +} + +@font-face { + font-family: "Chonburi"; + src: url(./Chonburi-Regular.ttf); + font-weight: 300; + font-style: normal +} + +@font-face { + font-family: "Charm"; + src: url(./Charm-Regular.ttf); + font-weight: 300; + font-style: normal +} + + + +.font-Thai-0 { + font-family: "Sarabun"; +} + +.font-Thai-1 { + font-family: "Kanit"; +} + +.font-Thai-2 { + font-family: "IBM Plex Sans Thai"; +} + +.font-Thai-3 { + font-family: "Mali"; +} + +.font-Thai-4 { + font-family: "Kodchasan"; +} + +.font-Thai-5 { + font-family: "Charm"; +} + +.font-Thai-6 { + font-family: "Chonburi"; +} \ No newline at end of file diff --git a/packages/prosody-ui/src/assets/icons/bookmark.svg b/packages/prosody-ui/src/assets/icons/bookmark.svg new file mode 100755 index 0000000..07c1129 --- /dev/null +++ b/packages/prosody-ui/src/assets/icons/bookmark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/prosody-ui/src/assets/icons/font.svg b/packages/prosody-ui/src/assets/icons/font.svg new file mode 100755 index 0000000..d4d5c72 --- /dev/null +++ b/packages/prosody-ui/src/assets/icons/font.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/packages/prosody-ui/src/assets/icons/heart.svg b/packages/prosody-ui/src/assets/icons/heart.svg new file mode 100755 index 0000000..f728e1e --- /dev/null +++ b/packages/prosody-ui/src/assets/icons/heart.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/prosody-ui/src/assets/icons/play.svg b/packages/prosody-ui/src/assets/icons/play.svg new file mode 100755 index 0000000..9a56073 --- /dev/null +++ b/packages/prosody-ui/src/assets/icons/play.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/packages/prosody-ui/src/assets/icons/quote.svg b/packages/prosody-ui/src/assets/icons/quote.svg new file mode 100755 index 0000000..34f5de9 --- /dev/null +++ b/packages/prosody-ui/src/assets/icons/quote.svg @@ -0,0 +1,28 @@ + + + + + + + + \ No newline at end of file diff --git a/packages/prosody-ui/src/assets/icons/react.svg b/packages/prosody-ui/src/assets/icons/react.svg new file mode 100755 index 0000000..6c87de9 --- /dev/null +++ b/packages/prosody-ui/src/assets/icons/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/prosody-ui/src/assets/icons/share.svg b/packages/prosody-ui/src/assets/icons/share.svg new file mode 100755 index 0000000..92c2b94 --- /dev/null +++ b/packages/prosody-ui/src/assets/icons/share.svg @@ -0,0 +1,28 @@ + + + + + + + + + diff --git a/packages/prosody-ui/src/assets/icons/speaker.svg b/packages/prosody-ui/src/assets/icons/speaker.svg new file mode 100644 index 0000000..a16db51 --- /dev/null +++ b/packages/prosody-ui/src/assets/icons/speaker.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + diff --git a/packages/prosody-ui/src/assets/icons/spinner.svg b/packages/prosody-ui/src/assets/icons/spinner.svg new file mode 100755 index 0000000..2a516de --- /dev/null +++ b/packages/prosody-ui/src/assets/icons/spinner.svg @@ -0,0 +1 @@ + diff --git a/packages/prosody-ui/src/components/Sentence.tsx b/packages/prosody-ui/src/components/Sentence.tsx new file mode 100644 index 0000000..33144ac --- /dev/null +++ b/packages/prosody-ui/src/components/Sentence.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import { notRandomFromArray } from "sortug"; +import "./sentence.css"; + +export function ColoredText({ + frags, + fn, + lang, +}: { + frags: string[]; + fn?: (s: string) => void; + lang?: string; +}) { + return ( + <> + {frags.map((s, i) => { + const prev = frags[i - 1]; + const prevC = prev ? notRandomFromArray(prev, colors) : "lol"; + const color = notRandomFromArray(s, colors); + const opacity = prev && prevC === color ? 0.8 : 1; + const style = { color, opacity }; + console.log({ style }); + return ; + })} + + ); +} + +export function CTInner({ + s, + style, + fn, + lang, +}: { + s: string; + style: any; + fn?: (s: string) => void; + lang?: string; +}) { + function handleClick(e: React.MouseEvent) { + console.log(!!fn, "fn"); + if (fn) fn(e.currentTarget.innerText.trim()); + } + return ( + + {s} + + ); +} +export const colors = [ + "#8c2c2c", + "#000000", + "#ffd400", + "#1513a0", + "#7e7e7e", + "1eb52d", +]; diff --git a/packages/prosody-ui/src/components/Word.tsx b/packages/prosody-ui/src/components/Word.tsx new file mode 100644 index 0000000..82939ce --- /dev/null +++ b/packages/prosody-ui/src/components/Word.tsx @@ -0,0 +1,119 @@ +import React, { useCallback, useEffect, useState } from "react"; +import spinner from "../assets/icons/spinner.svg"; +import likeIcon from "../assets/icons/heart.svg"; +import commentsIcon from "../assets/icons/quote.svg"; +import shareIcon from "../assets/icons/share.svg"; +import fontIcon from "../assets/icons/font.svg"; +import bookmarkIcon from "../assets/icons/bookmark.svg"; +import speakerIcon from "../assets/icons/speaker.svg"; +import type { AnalyzeRes, Meaning } from "../logic/types"; +import { ColoredText } from "./Sentence.tsx"; +import { P, Span, useSpeechSynthesis } from "../hooks/useLang.tsx"; + +function Word({ data, lang }: { data: AnalyzeRes; lang: string }) { + async function load() { + // const wiki = await fetchWiki(data.word); + // console.log(wiki, "wiki res"); + // if ("ok" in wiki) setM(wiki.ok.meanings); + // else setError(wiki.error); + // setLoading(false); + } + useEffect(() => { + load(); + }, []); + const [error, setError] = useState(""); + const [loading, setLoading] = useState(true); + const [meanings, setM] = useState([]); + const [font, setFont] = useState(0); + + function changeFont() { + if (font === 6) setFont(0); + else setFont(font + 1); + } + const { voices, speaking, speak, stop } = useSpeechSynthesis(); + function playAudio() { + console.log({ voices, speaking }); + console.log("word", data.word); + speak(data.word); + } + + async function saveW() {} + + return ( +
+ + +
+ +
+
+

{`/${data.ipa.replace(/\s/g, "")}/`}

+ +
+
+ {loading ? ( + + ) : ( + meanings.map((m) => ( +
+
+ {m.pos} +
+
    + {m.meaning.map((t, i) => ( +
  1. +

    {t}

    +
  2. + ))} +
+
+ )) + )} + {error &&
{error}
} +
+
+ ); +} + +export default Word; + +// function FloatingButtons({ +// tweet, +// avatar, +// changeFont, +// }: { +// tweet: Tweet; +// avatar: string; +// changeFont: any; +// }) { +// const { apiKeys, prompts, setModal } = useGlobalState(); +// function openUser() {} +// function openComments() {} +// function openShare() {} +// async function doLike() { +// const key = apiKeys.openai; +// // TODO hide button if key not set +// console.log(tweet.text, "whole text"); +// console.log(tweet.media, "media"); +// if (tweet.media[0] && !tweet.media[0].isVideo) { +// const res = await vision(tweet.media[0].url, "", key); +// console.log(res, "vision res"); +// } +// // const res = await translate(tweet.text, prompts.translate,key); +// // if ("ok" in res) +// // setModal() +// } +// async function doBookmark() {} +// return ( +//
+//
+// +//
+// +// +// +// +// +//
+// ); +// } diff --git a/packages/prosody-ui/src/components/sentence.css b/packages/prosody-ui/src/components/sentence.css new file mode 100644 index 0000000..0bd0a49 --- /dev/null +++ b/packages/prosody-ui/src/components/sentence.css @@ -0,0 +1,272 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +#root>.spinner { + width: 100px; + height: 100px; +} + +#entry>.spinner { + width: 80px; + height: 80px; +} + + + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} + +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} + +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} + +#cookies { + & .active { + background-color: var(--huang); + } + + & input { + margin-left: 1rem; + width: 100%; + } + + & textarea { + width: 100%; + height: 500px; + resize: none; + outline: none; + } +} + +#entry { + width: 100%; + height: 100%; + position: relative; + padding: 1rem; + /* prov */ + border: 2px solid black; + + & div[lang="th"] { + + & .tw-text, + & .tw-hashtag { + font-size: 3rem; + } + } + + & .text-wrapper { + display: block; + margin: 0.5rem 0; + /* overflow: hidden; */ + } + + & .word { + display: inline-block; + transition: transform 0.3s ease; + } + + & .word:hover { + transform: scale(1.4); + background-color: white; + } + + & #tw-media { + max-width: 100%; + + & img, + & video { + max-width: 100%; + } + } +} + +#inner { + height: 100%; + max-height: 100%; + overflow-y: auto; +} + +#entry-icons { + position: absolute; + bottom: 5%; + right: 5%; + width: 50px; + display: flex; + flex-direction: column; + gap: 1rem; + + & .avatar { + border: 2px solid black; + border-radius: 50%; + width: 50px; + height: 50px; + overflow: hidden; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + + & img { + width: 100%; + height: 100%; + object-fit: cover; + } + } +} + +#word-modal { + position: relative; + + & .font-icon { + position: absolute; + top: 0; + left: 0; + width: 32px; + height: 32px; + } + + & .save-icon { + position: absolute; + top: 0; + right: 0; + width: 32px; + height: 32px; + } + + & .original { + font-size: 4rem; + margin-bottom: 1rem; + } + + & .syllable {} + + & .IPA { + font-size: 1.6rem; + line-height: 1.6rem; + & img{ + width: 50px; + margin-left: 1rem; + } + } + + & .meanings { + + & .spinner { + width: 80px; + height: 80px; + } + + & .meaning { + margin: 1rem auto; + } + + & .pos { + font-size: 1.2rem; + margin-bottom: 0.3rem; + text-align: left; + } + + & ol { + word-wrap: normal; + margin: auto; + text-align: left; + } + } +} + +img { + width: 100%; + height: 100%; + object-fit: cover; +} +.flex1{ + width: 100%; + display: flex; + gap: 1rem; + align-items: center; +} +.flex-center{ + justify-content: center; +} + +/* p { */ +/* position: absolute; */ +/* top: 50%; */ +/* left: 50%; */ +/* transform: translate(-50%, -50%); */ +/* color: white; */ +/* background-color: rgba(0, 0, 0, 0.5); */ +/* padding: 10px; */ +/* border-radius: 5px; */ +/* } */ +#modal-bg{ + height: 100vh; + width: 100vw; + background-color: rgb(0, 0, 0, 0.9); + position: fixed; + top: 0; + left: 0; + z-index: 100; +} + +#modal-fg { + position: fixed; + top: 50%; + left: 50%; + width: 80%; + z-index: 101; + transform: translate(-50%, -50%); + /* background-color: var(--background-color); */ + background-color: lightgrey; + font-size: 1.2rem; + padding: 1rem; + max-height: 80%; + overflow-y: scroll; +} + + +.text-ipa{ + font-size: 1.5rem; +} +.text-thai{ + font-size: 1.5rem; +} + + +/* // new */ +.word.cp{ + margin: 0 0.5ch; +} diff --git a/packages/prosody-ui/src/components/word.css b/packages/prosody-ui/src/components/word.css new file mode 100644 index 0000000..e69de29 diff --git a/packages/prosody-ui/src/files.d.ts b/packages/prosody-ui/src/files.d.ts new file mode 100644 index 0000000..5e52f80 --- /dev/null +++ b/packages/prosody-ui/src/files.d.ts @@ -0,0 +1,4 @@ +declare module "*.svg" { + const content: string; + export default content; +} diff --git a/packages/prosody-ui/src/fonts/FontChanger.tsx b/packages/prosody-ui/src/fonts/FontChanger.tsx new file mode 100644 index 0000000..15c932e --- /dev/null +++ b/packages/prosody-ui/src/fonts/FontChanger.tsx @@ -0,0 +1,64 @@ +import React, { useEffect, useState, type ReactNode } from "react"; +import fontIcon from "../assets/icons/font.svg"; +import { getScriptPredictor } from "glotscript"; +import ThaiFontLoader from "./Thai"; + +function FontChanger({ text }: { text: string }) { + const [script, setScript] = useState(null); + useEffect(() => { + const predictor = getScriptPredictor(); + const res = predictor(text); + console.log("script predicted", res); + setScript(res[0]); + }, [text]); + useEffect(() => { + if (script === "Hani") setFontCount(12); + else if (script === "Thai") setFontCount(6); + else if (script === "Jpan") setFontCount(5); + // else if (script === "Latn") setFontCount(6) + }, [script]); + const [fontIdx, setFont] = useState(0); + const [fontCount, setFontCount] = useState(0); + function changeFont() { + if (fontIdx === fontCount) setFont(0); + else setFont((prev) => prev + 1); + } + return ( +
+ + {script === "Thai" ? : null} +
+ ); +} +// function FontChanger({ +// lang, +// children, +// }: { +// lang: string; +// children: ReactNode; +// }) { +// useEffect(() => {}, []); +// const [script, setScript] = useState("Latn"); +// const [fontIdx, setFont] = useState(0); +// const fontCount = 6; +// function changeFont() { +// if (fontIdx === fontCount) setFont(0); +// else setFont((prev) => prev + 1); +// } +// return ( +//
+// +// {children} +//
+// ); +// } + +export default FontChanger; diff --git a/packages/prosody-ui/src/fonts/Hani.tsx b/packages/prosody-ui/src/fonts/Hani.tsx new file mode 100644 index 0000000..f9cc602 --- /dev/null +++ b/packages/prosody-ui/src/fonts/Hani.tsx @@ -0,0 +1,14 @@ +import React, { useState, type ReactNode } from "react"; +import "../assets/fonts/Hani/style.css"; + +function ChineseFontLoader({ children }: { children: ReactNode }) { + const [fontIdx, setFont] = useState(0); + const fontCount = 12; + function changeFont() { + if (fontIdx === fontCount) setFont(0); + else setFont((prev) => prev + 1); + } + return
{children}
; +} + +export default ChineseFontLoader; diff --git a/packages/prosody-ui/src/fonts/Thai.tsx b/packages/prosody-ui/src/fonts/Thai.tsx new file mode 100644 index 0000000..0048316 --- /dev/null +++ b/packages/prosody-ui/src/fonts/Thai.tsx @@ -0,0 +1,8 @@ +import React, { useState, type ReactNode } from "react"; +import "../assets/fonts/Thai/style.css"; + +function ThaiFontLoader({ text }: { text: string }) { + return
{text}
; +} + +export default ThaiFontLoader; diff --git a/packages/prosody-ui/src/fonts/useLangFont.tsx b/packages/prosody-ui/src/fonts/useLangFont.tsx new file mode 100644 index 0000000..36fa603 --- /dev/null +++ b/packages/prosody-ui/src/fonts/useLangFont.tsx @@ -0,0 +1,44 @@ +import React, { useEffect, useState, type ReactNode } from "react"; +import fontIcon from "../assets/icons/font.svg"; +import { getScriptPredictor } from "glotscript"; + +function useLangFont({ text }: { text: string }) { + useEffect(() => { + const predictor = getScriptPredictor(); + const res = predictor(text); + console.log("script predicted", res); + setScript(res[0]); + }, [text]); + const [script, setScript] = useState(null); + const [fontIdx, setFont] = useState(0); + const fontCount = 6; + function changeFont() { + if (fontIdx === fontCount) setFont(0); + else setFont((prev) => prev + 1); + } + // if (script === "Hani") return {} +} +// function FontChanger({ +// lang, +// children, +// }: { +// lang: string; +// children: ReactNode; +// }) { +// useEffect(() => {}, []); +// const [script, setScript] = useState("Latn"); +// const [fontIdx, setFont] = useState(0); +// const fontCount = 6; +// function changeFont() { +// if (fontIdx === fontCount) setFont(0); +// else setFont((prev) => prev + 1); +// } +// return ( +//
+// +// {children} +//
+// ); +// } + +export default useLangFont; diff --git a/packages/prosody-ui/src/hooks/useLang.tsx b/packages/prosody-ui/src/hooks/useLang.tsx new file mode 100644 index 0000000..687c81d --- /dev/null +++ b/packages/prosody-ui/src/hooks/useLang.tsx @@ -0,0 +1,184 @@ +import { + useState, + useEffect, + createContext, + useContext, + useCallback, + type ElementType, +} from "react"; +type ScriptClass = + | "text-ipa" + | "text-rtl" + | "text-cjk" + | "text-thai" + | "text-cyrillic" + | "text-latin"; +interface ScriptContextType { + getClass: (text: string) => ScriptClass; +} +const ScriptContext = createContext({ + getClass: (text: string) => "text-latin" as ScriptClass, +}); + +const getScriptClass = (text: string): ScriptClass => { + // You can combine these with includes() if text has multiple scripts + if (/[\u0591-\u07FF\u200F\u202B]/.test(text)) return "text-rtl"; + + if (/[\u3040-\u30ff\u3400-\u4dbf\u4e00-\u9fff]/.test(text)) return "text-cjk"; + + if (/[\u0E00-\u0E7F]/.test(text)) return "text-thai"; + + if (/[\u0400-\u04FF]/.test(text)) return "text-cyrillic"; + + if (/[\u0250-\u02AF\u1D00-\u1D7F\u1D80-\u1DBF\u1DC0-\u1DFF]/.test(text)) + return "text-ipa"; + + return "text-latin"; // default +}; + +export const ScripProvider: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { + const getClass = useCallback((text: string) => { + return getScriptClass(text); + }, []); + + return ( + + {children} + + ); +}; + +export const useScript = () => useContext(ScriptContext); + +type TextElementProps = { + children?: React.ReactNode; + className?: string; +}; +const createTextElement = (Component: ElementType) => { + return function TextElement({ + children, + className, + ...rest + }: TextElementProps & React.ComponentPropsWithoutRef) { + const writingSystemClass = + typeof children === "string" ? getScriptClass(children) : "text-latin"; + + return ( + + {children} + + ); + }; +}; + +// Create all the text elements you need +export const Span = createTextElement("span"); +export const P = createTextElement("p"); +export const H1 = createTextElement("h1"); +export const H2 = createTextElement("h2"); +export const H3 = createTextElement("h3"); +export const H4 = createTextElement("h4"); +export const H5 = createTextElement("h5"); +export const H6 = createTextElement("h6"); +export const Label = createTextElement("label"); +export const Small = createTextElement("small"); + +interface Voice { + default: boolean; + lang: string; + localService: boolean; + name: string; + voiceURI: string; +} + +export const useSpeechSynthesis = () => { + const [voices, setVoices] = useState([]); + const [speaking, setSpeaking] = useState(false); + console.log({ voices }, "voices hook"); + + useEffect(() => { + // Function to get voices + const updateVoices = () => { + // Some browsers need a small delay for voices to be available + setTimeout(() => { + const availableVoices = window.speechSynthesis.getVoices(); + if (availableVoices.length > 0) { + setVoices(availableVoices); + } + }, 100); + }; + + // Get initial voices + updateVoices(); + + window.speechSynthesis.addEventListener("voiceschanged", updateVoices); + + // Cleanup + return () => { + window.speechSynthesis.removeEventListener("voiceschanged", updateVoices); + }; + }, []); + + const speak = (text: string, voiceName?: string) => { + const utterance = new SpeechSynthesisUtterance(text); + + if (voiceName) { + const voice = voices.find((v) => v.name === voiceName); + if (voice) utterance.voice = voice; + } + + utterance.onstart = () => setSpeaking(true); + utterance.onend = () => setSpeaking(false); + utterance.onerror = () => setSpeaking(false); + + window.speechSynthesis.speak(utterance); + }; + + const stop = () => { + window.speechSynthesis.cancel(); + setSpeaking(false); + }; + + return { + voices, + speaking, + speak, + stop, + }; +}; + +// Example usage in a component: +const SpeechComponent = () => { + const { voices, speaking, speak, stop } = useSpeechSynthesis(); + const [selectedVoice, setSelectedVoice] = useState(""); + + return ( +
+ + + + + {speaking && } +
+ ); +}; diff --git a/packages/prosody-ui/src/hooks/useModal.tsx b/packages/prosody-ui/src/hooks/useModal.tsx new file mode 100644 index 0000000..7164bcb --- /dev/null +++ b/packages/prosody-ui/src/hooks/useModal.tsx @@ -0,0 +1,53 @@ +import { franc } from "franc-all"; +import React, { + ReactElement, + ReactNode, + useCallback, + useEffect, + useRef, + useState, +} from "react"; + +function useModal() { + const [achild, setChild] = useState(null); + return setChild(null)}>{achild}; +} +export default useModal; + +function Modal({ + children, + height = "fit-content", + width = "80%", + close, +}: { + children: ReactNode; + close: () => void; + width?: any; + height?: any; +}) { + function onKey(event: any) { + if (event.key === "Escape") close(); + + useEffect(() => { + document.addEventListener("keyup", onKey); + return () => { + document.removeEventListener("keyup", onKey); + }; + }, [children]); + } + + function clickAway(e: React.MouseEvent) { + e.stopPropagation(); + if (!modalRef.current || !modalRef.current.contains(e.target as any)) + close(); + } + const modalRef = useRef(null); + const style = { width, height }; + return ( + + ); +} diff --git a/packages/prosody-ui/src/hooks/useTTS.tsx b/packages/prosody-ui/src/hooks/useTTS.tsx new file mode 100644 index 0000000..671d078 --- /dev/null +++ b/packages/prosody-ui/src/hooks/useTTS.tsx @@ -0,0 +1,3 @@ +function useTTS(text: string) {} + +export default useTTS; diff --git a/packages/prosody-ui/src/latin/LatinText.tsx b/packages/prosody-ui/src/latin/LatinText.tsx new file mode 100644 index 0000000..e5b13ff --- /dev/null +++ b/packages/prosody-ui/src/latin/LatinText.tsx @@ -0,0 +1,77 @@ +import React, { useCallback, useEffect, useState } from "react"; +import type { AnalyzeRes } from "../logic/types"; +import { ColoredText } from "../components/Sentence"; +import Word from "../components/Word"; +import { iso6393To1 } from "../logic/iso6393to1"; + +function segmentate( + text: string, + lang: string, + granularity: "sentence" | "word" | "grapheme", +) { + // TODO proper error handling here + console.log("segmenting", lang); + const la = iso6393To1[lang]; + const lng = la || lang; + const segmenter = new Intl.Segmenter(lng, { granularity }); + const segments = Array.from(segmenter.segment(text)); + console.log("seg", segments[0]); + return segments.reduce((acc: string[], s) => { + const trimmed = s.segment.trim(); + if (trimmed) return [...acc, trimmed]; + else return acc; + }, []); +} + +export default function LatinText({ + text, + lang, + openWord, +}: { + text: string; + lang: string; + openWord?: (word: string) => void; +}) { + useEffect(() => { + const sentences = segmentate(text, lang, "sentence"); + if (sentences) setSentences(sentences); + }, [text]); + const [sentences, setSentences] = useState([]); + console.log({ sentences }); + return ( + <> + {sentences.map((s, i) => ( + + ))} + + ); +} + +function Sentence({ + text, + lang, + openWord, +}: { + text: string; + lang: string; + + openWord?: (word: string) => void; +}) { + useEffect(() => { + const w = segmentate(text, lang, "word"); + if (w) setWords(w); + console.log({ words }); + }, [text]); + const [words, setWords] = useState([]); + console.log({ words }); + + // const [data, setData] = useState>({}); + const [word, setWord] = useState(); + + return ( + <> + ; + {word && } + + ); +} diff --git a/packages/prosody-ui/src/logic/iso6393to1.ts b/packages/prosody-ui/src/logic/iso6393to1.ts new file mode 100644 index 0000000..4c4deed --- /dev/null +++ b/packages/prosody-ui/src/logic/iso6393to1.ts @@ -0,0 +1,186 @@ +export const iso6393To1: Record = { + aar: "aa", + abk: "ab", + afr: "af", + aka: "ak", + amh: "am", + ara: "ar", + arg: "an", + asm: "as", + ava: "av", + ave: "ae", + aym: "ay", + aze: "az", + bak: "ba", + bam: "bm", + bel: "be", + ben: "bn", + bis: "bi", + bod: "bo", + bos: "bs", + bre: "br", + bul: "bg", + cat: "ca", + ces: "cs", + cha: "ch", + che: "ce", + chu: "cu", + chv: "cv", + cor: "kw", + cos: "co", + cre: "cr", + cym: "cy", + dan: "da", + deu: "de", + div: "dv", + dzo: "dz", + ell: "el", + eng: "en", + epo: "eo", + est: "et", + eus: "eu", + ewe: "ee", + fao: "fo", + fas: "fa", + fij: "fj", + fin: "fi", + fra: "fr", + fry: "fy", + ful: "ff", + gla: "gd", + gle: "ga", + glg: "gl", + glv: "gv", + grn: "gn", + guj: "gu", + hat: "ht", + hau: "ha", + hbs: "sh", + heb: "he", + her: "hz", + hin: "hi", + hmo: "ho", + hrv: "hr", + hun: "hu", + hye: "hy", + ibo: "ig", + ido: "io", + iii: "ii", + iku: "iu", + ile: "ie", + ina: "ia", + ind: "id", + ipk: "ik", + isl: "is", + ita: "it", + jav: "jv", + jpn: "ja", + kal: "kl", + kan: "kn", + kas: "ks", + kat: "ka", + kau: "kr", + kaz: "kk", + khm: "km", + kik: "ki", + kin: "rw", + kir: "ky", + kom: "kv", + kon: "kg", + kor: "ko", + kua: "kj", + kur: "ku", + lao: "lo", + lat: "la", + lav: "lv", + lim: "li", + lin: "ln", + lit: "lt", + ltz: "lb", + lub: "lu", + lug: "lg", + mah: "mh", + mal: "ml", + mar: "mr", + mkd: "mk", + mlg: "mg", + mlt: "mt", + mon: "mn", + mri: "mi", + msa: "ms", + mya: "my", + nau: "na", + nav: "nv", + nbl: "nr", + nde: "nd", + ndo: "ng", + nep: "ne", + nld: "nl", + nno: "nn", + nob: "nb", + nor: "no", + nya: "ny", + oci: "oc", + oji: "oj", + ori: "or", + orm: "om", + oss: "os", + pan: "pa", + pli: "pi", + pol: "pl", + por: "pt", + pus: "ps", + que: "qu", + roh: "rm", + ron: "ro", + run: "rn", + rus: "ru", + sag: "sg", + san: "sa", + sin: "si", + slk: "sk", + slv: "sl", + sme: "se", + smo: "sm", + sna: "sn", + snd: "sd", + som: "so", + sot: "st", + spa: "es", + sqi: "sq", + srd: "sc", + srp: "sr", + ssw: "ss", + sun: "su", + swa: "sw", + swe: "sv", + tah: "ty", + tam: "ta", + tat: "tt", + tel: "te", + tgk: "tg", + tgl: "tl", + tha: "th", + tir: "ti", + ton: "to", + tsn: "tn", + tso: "ts", + tuk: "tk", + tur: "tr", + twi: "tw", + uig: "ug", + ukr: "uk", + urd: "ur", + uzb: "uz", + ven: "ve", + vie: "vi", + vol: "vo", + wln: "wa", + wol: "wo", + xho: "xh", + yid: "yi", + yor: "yo", + zha: "za", + zho: "zh", + zul: "zu", +}; diff --git a/packages/prosody-ui/src/logic/stanza.ts b/packages/prosody-ui/src/logic/stanza.ts new file mode 100644 index 0000000..9e59450 --- /dev/null +++ b/packages/prosody-ui/src/logic/stanza.ts @@ -0,0 +1,86 @@ +import type { AsyncRes, Result } from "sortug"; + +const ENDPOINT = "http://localhost:8102"; +export async function segmenter(text: string, lang: string) { + try { + const body = JSON.stringify({ lang, string: text }); + const opts = { + headers: { "Content-type": "application/json" }, + method: "POST", + body, + }; + const res = await fetch(ENDPOINT + "/segment", opts); + console.log("stanza", res); + const j = await res.json(); + return { ok: j }; + } catch (e) { + return { error: `${e}` }; + } +} +export async function idLang(text: string) { + try { + const body = JSON.stringify({ string: text }); + const opts = { + headers: { "Content-type": "application/json" }, + method: "POST", + body, + }; + const res = await fetch(ENDPOINT + "/detect-lang", opts); + const j = await res.json(); + return { ok: j }; + } catch (e) { + return { error: `${e}` }; + } +} + +export type Sentence = { + text: string; + sentiment: number; + constituency: string; + dependencies: Dependency[]; + entities: Entity[]; + tokens: Token[]; + words: Word[]; +}; +export type Dependency = Array<[Word, string, Word]>; +export type Word = { + id: number; + text: string; + lemma: string; + upos: string; + xpos: string; + feats: string; + head: number; + deprel: string; + start_char: number; + end_char: number; +}; +export type Token = { + id: [number, number]; + text: string; + misc: string; + words: Word[]; + start_char: number; + end_char: number; + ner: string; +}; +export type Entity = { + text: string; + misc: string; + start_char: number; + end_char: number; + type: string; +}; +// "amod", +// { +// "id": 1, +// "text": "Stony", +// "lemma": "Stony", +// "upos": "ADJ", +// "xpos": "NNP", +// "feats": "Degree=Pos", +// "head": 3, +// "deprel": "amod", +// "start_char": 0, +// "end_char": 5 +// } diff --git a/packages/prosody-ui/src/logic/types.ts b/packages/prosody-ui/src/logic/types.ts new file mode 100644 index 0000000..ac308cf --- /dev/null +++ b/packages/prosody-ui/src/logic/types.ts @@ -0,0 +1,48 @@ +export type Cookie = { + domain: string; + path: string; + hostOnly: boolean; + httpOnly: boolean; + secure: boolean; + session: boolean; + sameSite: SameSite; + storeId: null; + name: string; + value: string; +}; +export type CookiesMap = Record; +export type CookieMap = Record; +export type KeyMap = Record; +type SameSite = null | "no_restriction"; // TODO + +export type APIRes = { API: { app: string; api_key: string } }; +export type CookieRes = { Cookie: { app: string; cookie: CookieMap } }; +export type CookiesRes = { cookies: CookiesMap; apiKeys: KeyMap }; + +// words +export type Meaning = { + pos: string; // part of speech; + meaning: string[]; + etymology: string; + references?: any; +}; + +export type Prompts = { + translate: string; +}; +export type AnalyzeRes = { + word: string; + syllables: string[]; + ipa: string; + pos: POS; +}; +type PosTuple = [string, POS]; +type POS = string; + +export type WordData = { + spelling: string; + lang: string; + ipa: string; + meanings: Meaning[]; + references?: any; +}; diff --git a/packages/prosody-ui/src/logic/utils.ts b/packages/prosody-ui/src/logic/utils.ts new file mode 100644 index 0000000..737a6ec --- /dev/null +++ b/packages/prosody-ui/src/logic/utils.ts @@ -0,0 +1,66 @@ +import type { Result } from "sortug"; + +export function detectScript(text: string): Result { + const scripts = { + Latin: /[\u0000-\u007F\u00A0-\u00FF\u0100-\u017F\u0180-\u024F]/g, + Cyrillic: /[\u0400-\u04FF\u0500-\u052F\u2DE0-\u2DFF\uA640-\uA69F]/g, + Greek: /[\u0370-\u03FF\u1F00-\u1FFF]/g, + Hebrew: /[\u0590-\u05FF]/g, + Arabic: /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF]/g, + Devanagari: /[\u0900-\u097F]/g, // Hindi, Sanskrit, etc. + Bengali: /[\u0980-\u09FF]/g, + Thai: /[\u0E00-\u0E7F]/g, + Chinese: + /[\u4E00-\u9FFF\u3400-\u4DBF\u20000-\u2A6DF\u2A700-\u2B73F\u2B740-\u2B81F]/g, + Japanese: /[\u3040-\u309F\u30A0-\u30FF\uFF00-\uFFEF\u4E00-\u9FAF]/g, // Includes Hiragana, Katakana + Korean: /[\uAC00-\uD7AF\u1100-\u11FF\u3130-\u318F]/g, // Includes Hangul + Armenian: /[\u0530-\u058F]/g, + Georgian: /[\u10A0-\u10FF]/g, + Khmer: /[\u1780-\u17FF]/g, // Cambodian + Myanmar: /[\u1000-\u109F]/g, // Burmese + Tamil: /[\u0B80-\u0BFF]/g, + Telugu: /[\u0C00-\u0C7F]/g, + Amharic: /[\u1200-\u137F]/g, // Ethiopian + }; + const counts: Record = {}; + + for (const [scriptName, regex] of Object.entries(scripts)) { + // Create an array of matches and count its length + const matches = text.match(regex) || []; + counts[scriptName] = matches.length; + } + + let maxCount = 0; + let dominantScript = "Unknown"; + + for (const [scriptName, count] of Object.entries(counts)) { + if (count > maxCount) { + maxCount = count; + dominantScript = scriptName; + } + } + if (dominantScript === "Unknown") return { error: "Not detected" }; + else return { ok: dominantScript }; +} + +export function langFromScript(script: string): Result { + if (script === "Thai") return { ok: "th" }; + if (script === "Japanese") return { ok: "ja" }; + if (script === "Chinese") return { ok: "zh" }; + if (script === "Korean") return { ok: "ko" }; + else return { error: "too generic" }; +} +export function scriptFromLang(lang: string, text: string): string { + if (lang == "th") return "Thai"; + if (lang == "tha") return "Thai"; + if (lang == "en") return "Engl"; + if (lang == "es") return "Span"; + if (lang == "cn") return "Hant"; + if (lang == "zh") return "Hant"; + if (lang == "ja") return "Japn"; + else { + const res = detectScript(text); + if ("ok" in res) return res.ok; + else return ""; + } +} diff --git a/packages/prosody-ui/src/logic/wiki.ts b/packages/prosody-ui/src/logic/wiki.ts new file mode 100644 index 0000000..1325c0f --- /dev/null +++ b/packages/prosody-ui/src/logic/wiki.ts @@ -0,0 +1,138 @@ +import type { AsyncRes, Result } from "sortug"; +import type { Meaning } from "./types"; + +export function buildWiktionaryURL(word: string) { + const params = new URLSearchParams(); + params.append("action", "parse"); + params.append("page", word); + params.append("format", "json"); + params.append("prop", "templates|text"); + params.append("formatversion", "2"); + + const p = params.toString(); + const url = `https://en.wiktionary.org/w/api.php?${p}`; + return url; +} + +// export async function fetchWordInWiki(url: string) { +// const opts = { method: "GET", body: null, headers: {} }; +// try { +// const res = await proxyCall(url, opts); +// console.log(res.headers.get("content-type")); +// const j = await res.json(); +// return { ok: j }; +// } catch (e) { +// return { error: `${e}` }; +// } +// } + +export type WikiRes = { + url: string; + meanings: Meaning[]; + ipa: string[]; +}; +const poses = [ + "noun", + "verb", + "adjective", + "adverb", + "conjunction", + "determiner", + "preposition", + "definitions", +]; + +export function parseWiktionary(html: string, url: string): Result { + try { + const dp = new DOMParser(); + const doc = dp.parseFromString(html, "text/html"); + const ipas = doc.querySelectorAll(".IPA"); + const headings = doc.querySelectorAll(".mw-heading"); + const ms: Meaning[] = []; + const doneIdx: number[] = []; + let currentRound: Meaning = { pos: "", meaning: [], etymology: "" }; + for (let [idx, h] of Array.from(headings).entries()) { + const headingType: string = (h.firstChild as any).innerText; + if (!headingType) continue; + const ht = headingType.toLowerCase(); + if (ht.includes("etymology")) currentRound.etymology = fillEtym(h); + else if (poses.includes(ht)) { + currentRound.pos = ht; + currentRound = fillMeaning(h, currentRound); + } + if (currentRound.pos) { + ms.push({ ...currentRound }); + currentRound = { pos: "", meaning: [], etymology: "" }; + } + if (ht === "references") break; // make sure it's one single language lol + } + const ipaStrings = Array.from(ipas).map((el: any) => el.innerText); + return { ok: { meanings: ms, ipa: ipaStrings, url } }; + } catch (e) { + return { error: `${e}` }; + } +} + +function fillMeaning(el: Element, m: Meaning) { + const sibling = el.nextElementSibling; + if (!sibling) return m; + if (sibling?.tagName.toLowerCase() === "ol") { + for (let li of Array.from(sibling.children)) { + if (li.tagName.toLowerCase() !== "li") continue; + if (li.className.includes("empty-elt")) continue; + m.meaning.push(li.innerHTML); + } + } + if (m.meaning.length === 0) return fillMeaning(sibling, m); + else return m; +} + +function fillEtym(el: Element, acc: string = ""): string { + const sibling = el.nextElementSibling; + if (!sibling) return acc; + if (sibling?.tagName.toLowerCase() === "p") acc += `\n${sibling.innerHTML}`; + if (!acc) return fillEtym(sibling, acc); + else return acc; +} + +export function parseWiktionaryo(html: string, url: string): Result { + try { + const dp = new DOMParser(); + const doc = dp.parseFromString(html, "text/html"); + const ipas = doc.querySelectorAll(".IPA"); + const ols = doc.querySelectorAll("ol"); + const ms = Array.from(ols).map((el) => { + let pos = ""; + let etymology = ""; + let meaning: string[] = []; + let posr = findPos(el); + if ("ok" in posr) pos = posr.ok; + for (let li of Array.from(el.children)) { + if (li.tagName !== "LI") continue; + meaning.push((li as any).innerText); + } + return { pos, meaning, etymology }; + }); + console.log(ipas, "ipa strings"); + console.log(ols, "lists in wiki"); + const ipaStrings = Array.from(ipas).map((el: any) => el.innerText); + return { ok: { meanings: ms, ipa: ipaStrings, url } }; + } catch (e) { + return { error: `${e}` }; + } +} + +function findPos(el: Element): Result { + let pichai = el.previousElementSibling; + console.log(pichai, "previous"); + if (!pichai) return { error: "no pichai" }; + if (pichai.classList.contains("mw-heading")) { + const h4 = pichai.querySelector("h4"); + const h3 = pichai.querySelector("h3"); + if (!h4 && !h3) return findPos(pichai); + else { + const id = (h4?.innerText || h3?.innerText)!; + return { ok: id }; + } + } else return findPos(pichai); +} diff --git a/packages/prosody-ui/src/sortug.css b/packages/prosody-ui/src/sortug.css new file mode 100644 index 0000000..c6280c0 --- /dev/null +++ b/packages/prosody-ui/src/sortug.css @@ -0,0 +1,248 @@ + +/* SORTUG CSS */ +/* variables */ +:root { + --bai: rgba(255, 255, 255, 1); + --baizi: rgba(230, 230, 230); + --hui: rgba(130, 130, 130, 1); + --hei: rgba(0, 0, 0, 1); + --hong: rgb(141, 15, 15, 1); + --huang: rgb(230, 180, 60, 1); + --lan: rgb(30, 60, 80, 1); +} + +[data-theme="dark"] { + --bg: hei; + --fg: baizi; +} + +[data-theme="light"] { + --bg: white; + --fg: black; +} + +* { + box-sizing: border-box; +} + +html, +body, +#root { + height: 100%; + min-height: 100%; + overscroll-behavior: none; + color: var(--fg); + -webkit-font-smoothing: antialiased; + margin: 0; +} + +/* tailwindy classes */ +.card { + padding: 1rem; + max-width: max-content; +} + +button, +.button { + max-width: max-content; + padding: 0.5rem; + border: 1px solid var(--fg); +} + +/* borders */ +.nb { + border: none; +} + +/* widths */ +.hw { + width: 50%; +} + +.qw { + width: 25%; +} + +.tqw { + width: 75%; +} + +/* flex */ +.row { + display: flex; + align-items: center; +} + +.sy { + overflow-y: scroll; +} + +.fsy { + overflow-y: scroll; + height: 100%; +} + +.fxc { + display: flex; + justify-content: center; + align-items: baseline; +} + +/* flex spread */ +.fs { + display: flex; + justify-content: space-between; +} + +.fsc { + display: flex; + justify-content: space-between; + align-items: center; +} + +.g1 { + gap: 0.5rem; +} + +.g2 { + gap: 1rem; +} + +.address { + font-family: "Courier New", Courier, monospace; +} + +.spread { + justify-content: space-between; +} + +.even { + justify-content: space-evenly; +} + +.flexc { + justify-content: center; +} + +.cp { + cursor: pointer; +} + +/* centering */ +.gc { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.agc { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.ac { + position: absolute; + left: 50%; + transform: translateX(-50%); +} + +.xc { + position: fixed; + left: 50%; + transform: translateX(-50%); + z-index: 20; +} + +.tc { + text-align: center; +} + +.bc { + display: block; + margin-left: auto; + margin-right: auto; +} + +.blocks { + & * { + display: block; + } +} + +.bold { + font-weight: 700; +} + +.weak { + opacity: 0.7; +} + +.all-c { + & * { + margin-left: auto; + margin-right: auto; + } +} + +.mb-1 { + margin-bottom: 1rem; +} + +.error { + color: red; + text-align: center; +} + +.tabs { + display: flex; + justify-content: space-evenly; + align-items: center; + + & .tab { + cursor: pointer; + opacity: 0.5; + } + + & .tab.active { + opacity: 1; + } +} + +.disabled { + opacity: 0.5; +} + +.smol { + font-size: 0.9rem; +} + +/* The Modal (background) */ +#modal-bg { + position: fixed; + z-index: 1; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgba(0, 0, 0, 0.4); + z-index: 998; +} + +/* Modal Content */ +#modal-fg { + background-color: var(--bg); + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + padding: 20px; + z-index: 999; + max-height: 90vh; + min-height: 20vh; + max-width: 90vw; + overflow: auto; +} diff --git a/packages/prosody-ui/src/styles/styles.css b/packages/prosody-ui/src/styles/styles.css new file mode 100644 index 0000000..69351f1 --- /dev/null +++ b/packages/prosody-ui/src/styles/styles.css @@ -0,0 +1,281 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +#root>.spinner { + width: 100px; + height: 100px; +} + +#entry>.spinner { + width: 80px; + height: 80px; +} + + + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} + +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} + +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} + +#cookies { + & .active { + background-color: var(--huang); + } + + & input { + margin-left: 1rem; + width: 100%; + } + + & textarea { + width: 100%; + height: 500px; + resize: none; + outline: none; + } +} + +#entry { + width: 100%; + height: 100%; + position: relative; + padding: 1rem; + /* prov */ + border: 2px solid black; + + & div[lang="th"] { + + & .tw-text, + & .tw-hashtag { + font-size: 3rem; + } + } + + & .text-wrapper { + display: block; + margin: 0.5rem 0; + /* overflow: hidden; */ + } + + & .word { + display: inline-block; + transition: transform 0.3s ease; + } + + & .word:hover { + transform: scale(1.4); + background-color: white; + } + + & #tw-media { + max-width: 100%; + + & img, + & video { + max-width: 100%; + } + } +} + +#inner { + height: 100%; + max-height: 100%; + overflow-y: auto; +} + +#entry-icons { + position: absolute; + bottom: 5%; + right: 5%; + width: 50px; + display: flex; + flex-direction: column; + gap: 1rem; + + & .avatar { + border: 2px solid black; + border-radius: 50%; + width: 50px; + height: 50px; + overflow: hidden; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + + & img { + width: 100%; + height: 100%; + object-fit: cover; + } + } +} + +#word-modal { + position: relative; + + & .font-icon { + position: absolute; + top: 0; + left: 0; + width: 32px; + height: 32px; + } + + & .save-icon { + position: absolute; + top: 0; + right: 0; + width: 32px; + height: 32px; + } + + & .original { + font-size: 4rem; + margin-bottom: 1rem; + } + + & .syllable {} + + & .IPA { + font-size: 1.6rem; + line-height: 1.6rem; + + & img { + width: 50px; + margin-left: 1rem; + } + } + + & .meanings { + + & .spinner { + width: 80px; + height: 80px; + } + + & .meaning { + margin: 1rem auto; + } + + & .pos { + font-size: 1.2rem; + margin-bottom: 0.3rem; + text-align: left; + } + + & ol { + word-wrap: normal; + margin: auto; + text-align: left; + } + } +} + +img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.flex1 { + width: 100%; + display: flex; + gap: 1rem; + align-items: center; +} + +.flex-center { + justify-content: center; +} + +/* p { */ +/* position: absolute; */ +/* top: 50%; */ +/* left: 50%; */ +/* transform: translate(-50%, -50%); */ +/* color: white; */ +/* background-color: rgba(0, 0, 0, 0.5); */ +/* padding: 10px; */ +/* border-radius: 5px; */ +/* } */ +#modal-bg { + height: 100vh; + width: 100vw; + background-color: rgb(0, 0, 0, 0.9); + position: fixed; + top: 0; + left: 0; + z-index: 100; +} + +#modal-fg { + position: fixed; + top: 50%; + left: 50%; + width: 80%; + z-index: 101; + transform: translate(-50%, -50%); + /* background-color: var(--background-color); */ + background-color: lightgrey; + font-size: 1.2rem; + padding: 1rem; + max-height: 80%; + overflow-y: scroll; +} + + +.text-ipa { + font-size: 1.5rem; +} + +.text-thai { + font-size: 1.5rem; +} + + +/* // new */ +.word.cp { + margin: 0 0.5ch; +} + +.lang-text-container { + display: flex; + flex-wrap: wrap; +} \ No newline at end of file diff --git a/packages/prosody-ui/src/thai/ThaiText.tsx b/packages/prosody-ui/src/thai/ThaiText.tsx new file mode 100644 index 0000000..fc1e1e6 --- /dev/null +++ b/packages/prosody-ui/src/thai/ThaiText.tsx @@ -0,0 +1,49 @@ +import React, { useCallback, useEffect, useState } from "react"; +import "../assets/fonts/Thai/style.css"; +import { segmentateThai } from "./logic/thainlp"; +import type { AnalyzeRes } from "../logic/types"; +import { ColoredText } from "../components/Sentence"; +import Word from "../components/Word"; + +export default function ThaiText({ + text, + openWord, +}: { + text: string; + openWord: (s: string) => void; +}) { + useEffect(() => { + pythonseg(); + }, [text]); + + const [data, setData] = useState>({}); + const [modal, setModal] = useState(); + const pythonseg = useCallback(async () => { + const s2 = await segmentateThai(text.trim()); + if ("ok" in s2) { + const ob = s2.ok.reduce((acc, item) => { + acc[item.word] = item; + return acc; + }, {} as any); + setData(ob); + console.log(s2, "s2"); + } else console.error(s2.error); + }, [text]); + + // function openWord(e: React.MouseEvent) { + // const s = e.currentTarget.innerText; + // const d = data[s]; + // setModal(d); + // // setModal(); + // } + return ( +
+ + {modal && } +
+ ); +} + +function ThaiWord() { + return
; +} diff --git a/packages/prosody-ui/src/thai/logic/thainlp.ts b/packages/prosody-ui/src/thai/logic/thainlp.ts new file mode 100644 index 0000000..031bf4c --- /dev/null +++ b/packages/prosody-ui/src/thai/logic/thainlp.ts @@ -0,0 +1,90 @@ +import type { AsyncRes } from "sortug"; +import type { AnalyzeRes } from "../../logic/types"; + +const ENDPOINT = "http://192.168.1.110:8001"; +async function call(path: string, body: any) { + try { + const opts = { + method: "POST", + headers: { "Content-type": "application/json" }, + body: JSON.stringify(body), + }; + const r1 = await fetch(ENDPOINT + path, opts); + // const r2 = await fetch(`http://192.168.1.110:8000/analyze`, opts); + const jj = await r1.json(); + return { ok: jj }; + } catch (e) { + return { error: `${e}` }; + } +} +export async function analyzeTHWord(word: string): AsyncRes { + return await call("/analyze", { word }); +} +export async function segmentateThai(sentence: string): AsyncRes { + return await call("/segmentate", { word: sentence }); +} + +export const POSMAP: Record = { + ADJ: "Adjective", + ADP: "Adposition", + ADV: "Adverb", + AUX: "Auxiliary", + CCONJ: "Coordinating conjunction", + DET: "Determiner", + INTJ: "Interjection", + NOUN: "Noun", + NUM: "Numeral", + PART: "Particle", + PRON: "Pronoun", + PROPN: "Proper noun", + PUNCT: "Punctuation", + SCONJ: "Subordinating conjunction", + VERB: "Verb", + NPRP: "Proper noun", + NCNM: "Cardinal number", + NONM: "Ordinal number", + NLBL: "Label noun", + NCMN: "Common noun", + NTTL: "Title noun", + PPRS: "Personal pronoun", + PDMN: "Demonstrative pronoun", + PNTR: "Interrogative pronoun", + PREL: "Relative pronoun", + VACT: "Active verb", + VSTA: "Stative verb", + VATT: "Attributive verb", + XVBM: "Pre-verb auxiliary, before negator “ไม่”", + XVAM: "Pre-verb auxiliary, after negator “ไม่”", + XVMM: "Pre-verb, before or after negator “ไม่”", + XVBB: "Pre-verb auxiliary, in imperative mood", + XVAE: "Post-verb auxiliary", + DDAN: "classifier in between", + DDAC: "in between", + DDBQ: "classifier or preceding quantitative expression", + DDAQ: "following quantitative expression", + DIAC: "classifier in between", + DIBQ: "classifier or preceding quantitative expression", + DIAQ: "following quantitative expression", + DCNM: "Determiner, cardinal number expression", + DONM: "Determiner, ordinal number expression", + ADVN: "Adverb with normal form", + ADVI: "Adverb with iterative form", + ADVP: "Adverb with prefixed form", + ADVS: "Sentential adverb", + CNIT: "Unit classifier", + CLTV: "Collective classifier", + CMTR: "Measurement classifier", + CFQC: "Frequency classifier", + CVBL: "Verbal classifier", + JCRG: "Coordinating conjunction", + JCMP: "Comparative conjunction", + JSBR: "Subordinating conjunction", + RPRE: "Preposition", + INT: "Interjection", + FIXN: "Nominal prefix", + FIXV: "Adverbial prefix", + EAFF: "Ending for affirmative sentence", + EITT: "Ending for interrogative sentence", + NEG: "Negator", + PUNC: "Punctuation", +}; diff --git a/packages/prosody-ui/src/zoom/FullText.tsx b/packages/prosody-ui/src/zoom/FullText.tsx new file mode 100644 index 0000000..ec85f09 --- /dev/null +++ b/packages/prosody-ui/src/zoom/FullText.tsx @@ -0,0 +1,60 @@ +import React from "react"; +import { motion, AnimatePresence } from "motion/react"; +import Paragraph from "./Paragraph"; +import { useZoom } from "./hooks/useZoom"; +import { containerVariants, buttonVariants } from "./animations"; +import { NLP } from "sortug-ai"; + +interface TextFocusMorphProps { + text: string; + doc: NLP.Spacy.SpacyRes; +} + +const FullText: React.FC = ({ text, doc }) => { + const { viewState, navigateBack, handleElementClick } = useZoom(); + const { level } = viewState; + + // Split text into paragraphs + const paragraphs = text + .split("\n\n") + .map((p) => p.trim()) + .filter(Boolean); + + return ( +
+ {level !== "text" && ( + + + ← Back + + + )} + + + {paragraphs.map((paragraph, idx) => ( + + ))} + +
+ ); +}; + +export default FullText; diff --git a/packages/prosody-ui/src/zoom/Paragraph.tsx b/packages/prosody-ui/src/zoom/Paragraph.tsx new file mode 100644 index 0000000..c26f806 --- /dev/null +++ b/packages/prosody-ui/src/zoom/Paragraph.tsx @@ -0,0 +1,60 @@ +import React, { memo, useCallback, useEffect, useState } from "react"; +import { motion } from "motion/react"; +import type { ViewProps, LoadingStatus } from "./logic/types"; +import { NLP } from "sortug-ai"; +import Sentence from "./Sentence"; +import { paragraphVariants, createHoverEffect } from "./animations"; +import { useZoom } from "./hooks/useZoom"; + +function Paragraph({ rawText, context, idx, doc }: ViewProps) { + const { viewState, handleElementClick } = useZoom(); + const { level, pIndex } = viewState; + const selected = pIndex === idx; + const isFocused = level === "paragraph" && selected; + + // State for sentences + const [loading, setLoading] = useState("pending"); + + return ( + <> + handleElementClick(e, idx)} + whileHover={ + level === "text" + ? createHoverEffect(level, "text", "255, 255, 200") + : {} + } + > + {loading === "loading" &&
} + {level === "text" || !selected || doc.segs.length === 0 ? ( +

{rawText}

+ ) : ( +
+ {doc.segs.map((sentence, sentIdx) => ( + s.text), + }} + doc={doc} + /> + ))} +
+ )} + + + ); +} + +export default memo(Paragraph); diff --git a/packages/prosody-ui/src/zoom/Sentence.tsx b/packages/prosody-ui/src/zoom/Sentence.tsx new file mode 100644 index 0000000..1d90346 --- /dev/null +++ b/packages/prosody-ui/src/zoom/Sentence.tsx @@ -0,0 +1,46 @@ +import React, { memo } from "react"; +import { motion } from "motion/react"; +import type { ViewProps, LoadingStatus } from "./logic/types"; +import { NLP } from "sortug-ai"; +import SpacyClause from "./SpacyClause"; +import { sentenceVariants, createHoverEffect } from "./animations"; +import { useZoom } from "./hooks/useZoom"; + +interface Props extends ViewProps { + spacy: NLP.Spacy.Sentence; + stanza?: NLP.Stanza.Sentence; +} + +function Sentence({ spacy, stanza, context, idx }: Props) { + const { viewState, handleElementClick } = useZoom(); + const { level, sIndex } = viewState; + const selected = sIndex === idx; + const isFocused = level === "sentence" && selected; + + return ( + <> + handleElementClick(e, idx)} + whileHover={ + level === "paragraph" + ? createHoverEffect(level, "paragraph", "200, 220, 255") + : {} + } + > + {level === "paragraph" || !selected ? ( + {spacy.text} + ) : ( + + )} + + + ); +} + +export default memo(Sentence); diff --git a/packages/prosody-ui/src/zoom/SpacyClause.tsx b/packages/prosody-ui/src/zoom/SpacyClause.tsx new file mode 100644 index 0000000..6b6f178 --- /dev/null +++ b/packages/prosody-ui/src/zoom/SpacyClause.tsx @@ -0,0 +1,125 @@ +import React, { memo, useState } from "react"; +import { motion } from "motion/react"; +import "./spacy.css"; +import { NLP } from "sortug-ai"; +// import { clauseVariants, createHoverEffect } from "./animations"; +// import { useZoom } from "./hooks/useZoom"; + +function Grammar({ sentence }: { sentence: NLP.Spacy.Sentence }) { + const [hoveredClause, setHoveredClause] = useState(null); + + // Ref to manage the timeout for debouncing mouse leave + return ( +
+ {sentence.words.map((w, idx) => { + const isRoot = + w.ancestors.length === 0 || w.dep.toLowerCase() === "root"; + const isSubj = NLP.Spacy.isChild(w, sentence.subj.id); + const isPred = !isSubj && !isRoot; + const predClass = isPred ? "pred" : ""; + const relClass = isRoot ? "root" : `rel-${w.dep}`; + const ownClass = isRoot + ? "" + : isSubj + ? "subj" + : w.children.length === 0 + ? "" + : `clause-${w.id}`; + const clase = w.ancestors.reduce((acc, item) => { + if (item === sentence.subj.id || item === sentence.root.id) + return acc; + else return `${acc} clause-${item}`; + }, ``); + const className = `suword ${relClass} ${ownClass} ${clase} ${predClass}`; + const isHovering = + !isRoot && + !!hoveredClause && + (w.id === hoveredClause || w.ancestors.includes(hoveredClause)); + function handleClick(w: NLP.Spacy.Word) { + console.log("show the whole clause and all that", w); + } + return ( + + ); + })} +
+ ); +} + +const spanVariants: any = { + initial: { + // Base style + backgroundColor: "rgba(0, 0, 0, 0)", // Transparent background initially + fontWeight: "normal", + scale: 1, + zIndex: 0, // Default stacking + position: "relative", // Needed for zIndex to work reliably + // Add other base styles if needed + }, + hovered: { + // Style when this span's group is hovered + backgroundColor: "rgba(255, 255, 0, 0.5)", // Yellow highlight + scale: 1.05, + zIndex: 1, // Bring hovered spans slightly forward + boxShadow: "0px 2px 5px rgba(0,0,0,0.2)", + // Add other hover effects + }, +}; + +// Define the transition +const spanTransition = { + type: "spring", + stiffness: 500, + damping: 30, + // duration: 0.1 // Or use duration for non-spring types +}; + +function ClauseSpan({ + word, + className, + hovering, + setHovering, + onClick, +}: { + word: NLP.Spacy.Word; + className: string; + hovering: boolean; + setHovering: (n: number | null) => void; + onClick: (w: NLP.Spacy.Word) => void; +}) { + function handleMouseOver() { + setHovering(word.id); + // if (word.children.length > 0) setHovering(word.id); + // else setHovering(word.head); + } + function handleMouseLeave() { + setHovering(null); + } + function handleClick(e: React.MouseEvent) { + e.stopPropagation(); + onClick(word); + } + return ( + + {word.text} + + ); +} + +export default memo(Grammar); diff --git a/packages/prosody-ui/src/zoom/animations.ts b/packages/prosody-ui/src/zoom/animations.ts new file mode 100644 index 0000000..6135e7f --- /dev/null +++ b/packages/prosody-ui/src/zoom/animations.ts @@ -0,0 +1,199 @@ +import type { Variants } from "motion/react"; + +// Base transition configurations for consistent animations +const baseTransition = { + duration: 0.5, + ease: [0.43, 0.13, 0.23, 0.96], // Improved easing for smoother feel +}; + +export const fadeTransition = { + ...baseTransition, + duration: 0.3, +}; + +// Shared variants for different view levels +export const containerVariants: Variants = { + text: { + opacity: 1, + transition: { + staggerChildren: 0.05, + delayChildren: 0.1, + }, + }, + paragraph: { + opacity: 1, + transition: { + staggerChildren: 0.05, + delayChildren: 0.1, + }, + }, + sentence: { + opacity: 1, + transition: { + staggerChildren: 0.05, + delayChildren: 0.1, + }, + }, + clause: { + opacity: 1, + transition: { + staggerChildren: 0.05, + delayChildren: 0.1, + }, + }, + word: { + opacity: 1, + transition: { + staggerChildren: 0.05, + delayChildren: 0.1, + }, + }, + syllable: { + opacity: 1, + transition: { + staggerChildren: 0.05, + delayChildren: 0.1, + }, + }, + phoneme: { + opacity: 1, + transition: { + staggerChildren: 0.05, + delayChildren: 0.1, + }, + }, +}; + +// Function to create element variants based on selection state +export const createElementVariants = ( + currentLevel: string, + nextLevel: string, + prevLevel: string, + selectedOpacity = 1, + unselectedOpacity = 0.1, + selectedScale = 1.05, + unselectedScale = 0.95, + selectedBlur = "0px", + unselectedBlur = "2px", + bgColor = "rgba(255, 255, 255, 0)", // Use rgba with 0 opacity instead of transparent +): Variants => { + return { + [prevLevel]: { + opacity: 1, + scale: 1, + filter: "blur(0px)", + backgroundColor: "rgba(255, 255, 255, 0)", // Use rgba with 0 opacity + transition: baseTransition, + }, + [currentLevel]: (isSelected: boolean) => ({ + opacity: isSelected ? selectedOpacity : unselectedOpacity, + scale: isSelected ? selectedScale : unselectedScale, + filter: isSelected ? `blur(${selectedBlur})` : `blur(${unselectedBlur})`, + backgroundColor: isSelected ? bgColor : "rgba(255, 255, 255, 0)", // Use rgba with 0 opacity + transition: baseTransition, + }), + [nextLevel]: (isSelected: boolean) => ({ + opacity: isSelected ? selectedOpacity : unselectedOpacity / 2, + scale: isSelected ? selectedScale : unselectedScale * 0.95, + filter: isSelected + ? `blur(${selectedBlur})` + : `blur(${parseInt(unselectedBlur) + 1}px)`, + backgroundColor: isSelected ? bgColor : "rgba(255, 255, 255, 0)", // Use rgba with 0 opacity + transition: baseTransition, + }), + }; +}; + +// Pre-configured variants for each level +export const paragraphVariants = createElementVariants( + "paragraph", + "sentence", + "text", + 1, + 0.1, + 1.05, + 0.95, + "0px", + "2px", + "rgba(200, 220, 255, 0.1)", +); + +export const sentenceVariants = createElementVariants( + "sentence", + "clause", + "paragraph", + 1, + 0.1, + 1.1, + 0.95, + "0px", + "2px", + "rgba(200, 220, 255, 0.2)", +); + +export const clauseVariants = createElementVariants( + "clause", + "word", + "sentence", + 1, + 0.1, + 1.1, + 0.95, + "0px", + "2px", + "rgba(220, 200, 255, 0.2)", +); + +export const wordVariants = createElementVariants( + "word", + "syllable", + "clause", + 1, + 0.1, + 1.15, + 0.9, + "0px", + "2px", + "rgba(255, 200, 200, 0.2)", +); + +export const syllableVariants = createElementVariants( + "syllable", + "phoneme", + "word", + 1, + 0.1, + 1.2, + 0.9, + "0px", + "2px", + "rgba(200, 255, 200, 0.2)", +); + +// Button animations +export const buttonVariants: Variants = { + initial: { opacity: 0, x: -20 }, + animate: { opacity: 1, x: 0, transition: fadeTransition }, + exit: { opacity: 0, x: -20, transition: fadeTransition }, +}; + +// Hover effects +export const createHoverEffect = ( + level: string, + currentLevel: string, + color: string, +) => { + if (level === currentLevel) { + return { + scale: 1.02, + backgroundColor: `rgba(${color}, 0.3)`, + transition: { duration: 0.2 }, + }; + } + return { + // Return empty animation with same properties to avoid errors + scale: 1, + backgroundColor: "rgba(255, 255, 255, 0)", + transition: { duration: 0.2 }, + }; +}; diff --git a/packages/prosody-ui/src/zoom/hooks/useZoom.tsx b/packages/prosody-ui/src/zoom/hooks/useZoom.tsx new file mode 100644 index 0000000..733ca06 --- /dev/null +++ b/packages/prosody-ui/src/zoom/hooks/useZoom.tsx @@ -0,0 +1,135 @@ +import React, { + createContext, + useState, + useContext, + type ReactNode, +} from "react"; +import type { ViewLevel, ViewState } from "../logic/types"; + +// Type definitions for the context +interface ZoomContextType { + viewState: ViewState; + setLevel: (level: ViewLevel) => void; + setParagraphIndex: (idx: number | null) => void; + setSentenceIndex: (idx: number | null) => void; + setClauseIndex: (idx: number | null) => void; + setWordIndex: (idx: number | null) => void; + setSyllableIndex: (idx: number | null) => void; + setPhonemeIndex: (idx: number | null) => void; + navigateBack: () => void; + handleElementClick: (e: React.MouseEvent, idx: number) => void; +} + +// Create the context with default empty values +const ZoomContext = createContext({ + viewState: { + level: "text", + pIndex: null, + sIndex: null, + cIndex: null, + wIndex: null, + yIndex: null, + fIndex: null, + }, + setLevel: () => {}, + setParagraphIndex: () => {}, + setSentenceIndex: () => {}, + setClauseIndex: () => {}, + setWordIndex: () => {}, + setSyllableIndex: () => {}, + setPhonemeIndex: () => {}, + navigateBack: () => {}, + handleElementClick: () => {}, +}); + +// Provider component +export const ZoomProvider: React.FC<{ children: ReactNode }> = ({ + children, +}) => { + const [viewState, setViewState] = useState({ + level: "text", + pIndex: null, + sIndex: null, + cIndex: null, + wIndex: null, + yIndex: null, + fIndex: null, + }); + + // Helper functions to update individual parts of the state + const setLevel = (level: ViewLevel) => + setViewState((prev) => ({ ...prev, level })); + const setParagraphIndex = (pIndex: number | null) => + setViewState((prev) => ({ ...prev, pIndex })); + const setSentenceIndex = (sIndex: number | null) => + setViewState((prev) => ({ ...prev, sIndex })); + const setClauseIndex = (cIndex: number | null) => + setViewState((prev) => ({ ...prev, cIndex })); + const setWordIndex = (wIndex: number | null) => + setViewState((prev) => ({ ...prev, wIndex })); + const setSyllableIndex = (yIndex: number | null) => + setViewState((prev) => ({ ...prev, yIndex })); + const setPhonemeIndex = (fIndex: number | null) => + setViewState((prev) => ({ ...prev, fIndex })); + + // Handle navigation levels + const navigateBack = () => { + const { level } = viewState; + + if (level === "paragraph") { + setViewState((prev) => ({ ...prev, level: "text", pIndex: null })); + } else if (level === "sentence") { + setViewState((prev) => ({ ...prev, level: "paragraph", sIndex: null })); + } else if (level === "clause") { + setViewState((prev) => ({ ...prev, level: "sentence", cIndex: null })); + } else if (level === "word") { + setViewState((prev) => ({ ...prev, level: "clause", wIndex: null })); + } else if (level === "syllable") { + setViewState((prev) => ({ ...prev, level: "word", yIndex: null })); + } else if (level === "phoneme") { + setViewState((prev) => ({ ...prev, level: "syllable", fIndex: null })); + } + }; + + // Handle clicks on elements to navigate forward + const handleElementClick = (e: React.MouseEvent, idx: number) => { + e.stopPropagation(); + const { level } = viewState; + + if (level === "text") { + setViewState((prev) => ({ ...prev, level: "paragraph", pIndex: idx })); + } else if (level === "paragraph") { + setViewState((prev) => ({ ...prev, level: "sentence", sIndex: idx })); + } else if (level === "sentence") { + setViewState((prev) => ({ ...prev, level: "clause", cIndex: idx })); + } else if (level === "clause") { + setViewState((prev) => ({ ...prev, level: "word", wIndex: idx })); + } else if (level === "word") { + setViewState((prev) => ({ ...prev, level: "syllable", yIndex: idx })); + } else if (level === "syllable") { + setViewState((prev) => ({ ...prev, level: "phoneme", fIndex: idx })); + } + }; + + return ( + + {children} + + ); +}; + +// Custom hook to use the zoom context +export const useZoom = () => useContext(ZoomContext); diff --git a/packages/prosody-ui/src/zoom/index.ts b/packages/prosody-ui/src/zoom/index.ts new file mode 100644 index 0000000..baf5db1 --- /dev/null +++ b/packages/prosody-ui/src/zoom/index.ts @@ -0,0 +1,8 @@ +export { ZoomProvider, useZoom } from "./hooks/useZoom"; +import Paragraph from "./Paragraph"; +import FullText from "./FullText"; +import Sentence from "./Paragraph"; +import SpacyClause from "./SpacyClause"; +import type * as Types from "./logic/types"; + +export { Paragraph, FullText, Sentence, SpacyClause, Types }; diff --git a/packages/prosody-ui/src/zoom/logic/types.ts b/packages/prosody-ui/src/zoom/logic/types.ts new file mode 100644 index 0000000..bea68ff --- /dev/null +++ b/packages/prosody-ui/src/zoom/logic/types.ts @@ -0,0 +1,53 @@ +import type { NLP } from "sortug-ai"; + +export type ViewLevel = + | "text" + | "paragraph" + | "sentence" + | "clause" + | "word" + | "syllable" + | "phoneme"; +export interface ViewState { + level: ViewLevel; + pIndex: number | null; + sIndex: number | null; + cIndex: number | null; + wIndex: number | null; + yIndex: number | null; + fIndex: number | null; +} + +export interface ViewProps { + idx: number; + rawText: string; + context: Context; + doc: NLP.Spacy.SpacyRes; +} +export type Context = { + parentText: string; + segmented: string[]; + idx: number; +}; + +export type WordData = { + confidence: number; + frequency: number | null; + id: number; + ipa: Array<{ ipa: string; tags: string[] }>; + spelling: string; + type: ExpressionType; + syllables: number; + lang: string; + prosody: any; + senses: Sense[]; +}; +export type ExpressionType = "word" | "expression" | "syllable"; +export type Sense = { + etymology: string; + pos: string; + forms: Array<{ form: string; tags: string[] }>; + related: any; + senses: Array<{ glosses: string[]; links: Array<[string, string]> }>; +}; +export type LoadingStatus = "pending" | "loading" | "success" | "error"; diff --git a/packages/prosody-ui/src/zoom/spacy.css b/packages/prosody-ui/src/zoom/spacy.css new file mode 100644 index 0000000..0077119 --- /dev/null +++ b/packages/prosody-ui/src/zoom/spacy.css @@ -0,0 +1,39 @@ +.suword { + margin-left: 0.5ch; + margin-right: 0.5ch; +} + +/* .suword.pred { */ +/* color: gold; */ +/* } */ + +/* Clause level */ +.clause-container { + max-width: 600px; + white-space: normal !important; + hyphens: auto; + + padding: 2px; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.2s ease; + will-change: transform, opacity, filter, background-color; + + span { + white-space: normal !important; + } +} + +.clause-container.selected { + background-color: rgba(220, 200, 255, 0.2); + z-index: 3; +} + +.suword.subj { + color: blue; + /* border-bottom: 2px solid blue; */ +} + +.suword.root { + color: darkred; +} \ No newline at end of file -- cgit v1.2.3