-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.html
286 lines (264 loc) · 22.1 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>UTF-C Demo Page</title>
<script src="js/utf-c.js"></script>
<script src="js/scsu.js"></script>
<style>
body {
margin: 0;
font-family: Trebuchet MS, Lucida Sans Unicode, Lucida Grande, Tahoma, Geneva, sans-serif;
font-size: 14px;
color: #24292e;
line-height: 1.5;
display: flex;
/* align-items: center; */
justify-content: center;
min-height: 100vh;
padding: 0 24px;
}
p, #input {
font-size: 16px;
}
main {
max-width: 800px;
padding: 24px 0;
}
#input {
width: 100%;
height: 30vh;
border: 1px solid #6cc3f9;
border-radius: 4px;
padding: 4px 6px;
box-sizing: border-box;
}
#input:focus {
border: 2px solid #6cc3f9;
border-radius: 4px;
outline: none;
padding: 3px 5px;
}
h1 {
text-align: center;
}
code, pre {
font-family: Lucida Console, Monaco, monospace;
font-size: 0.9em;
}
#control, .byte {
background: #6cc3f9;
color: #fff;
padding: 0px 3px;
border-radius: 2px;
margin-right: 3px;
line-height: 17px;
}
#control {
display: block;
padding: 3px;
}
.byte {
display: inline-block;
width: 16px;
text-align: center;
}
.enc {
width: 150px;
display: inline-block;
margin-top: 4px;
}
#stats, #compare-utf8, #compare-scsu {
text-align: center;
font-size: 14px;
color: #999;
}
.green {
color: mediumseagreen;
font-weight: bold;
}
.red {
color: orangered;
font-weight: bold;
}
.toggle, .sample {
cursor: pointer;
border-bottom: 1px dotted #6cc3f9;
display: inline-block;
line-height: 14px;
color: #4da8e0;
}
.toggle {
margin-left: 2px;
}
.sample {
margin-right: 10px;
}
a, a:visited {
color: #4da8e0;
}
</style>
</head>
<body>
<main>
<h1>UTF-C Demo</h1>
<p><a href="https://github.com/deNULL/utf-c">UTF-C</a> offers a compact way to store Unicode strings. Using the text field below you can test it on any text and compare its effectiveness to UTF-8 and SCSU. You can read more about the algorithm on <a href="https://github.com/deNULL/utf-c">Github</a> or inspect <a href="https://github.com/deNULL/utf-c/blob/master/js/utf-c.js#L78">the source code</a> directly.</p>
<div><span class="enc">Try a sample text:</span><span id="samples"></span></div>
<textarea id="input" oninput="updateText()">UTF-C supports all Unicode characters: русский, العربية, 한국어, עברית, ქართული, Ελληνικά, 日本語 🔥🎉👍</textarea>
<div id="stats"></div>
<div>
<span class="enc">UTF-8 (<span id="stats-utf8"></span>): </span><span id="result-utf8"></span>
</div>
<div>
<span class="enc">SCSU (<span id="stats-scsu"></span>): </span><span id="result-scsu"></span>
</div>
<div>
<span class="enc">UTF-C (<span id="stats-utfc"></span>): </span><span id="result-utfc"></span>
</div>
<div id="compare-utf8"></div>
<div id="compare-scsu"></div>
<div>
<span class="enc">Decoded back as: </span><span id="control"></span> <span id="control-info"></span>
</div>
</main>
<script>
const samples = [{
name: 'English',
content: 'UTF-C, just like UTF-8 and SCSU, is ASCII-compatible. That means that every text (like this one) containing only ASCII characters is represented exactly in the same way in all those encodings.',
}, {
name: 'Hebrew',
content: 'מחלקת היונקים היא אחת המחלקות המפותחות והמגוונות ביותר שחיות על פני כדור הארץ. היא כוללת בעלי חיים ממשקל של 2 גרם עד משקל של 180 טונות, מטילי ביצים או יולדים, אשר מאכלסים את מרבית האזורים הגאוגרפים ובתי-הגידול. יש בהם שוכני-יבשה ההולכים על ארבע רגליים או על שתיים, שוכני-ים מובהקים, בעלי חיים מעופפים, מטפסים על עצים ושוכני מחילות תת-קרקעיות. האדם משתייך אף הוא למחלקת היונקים.',
}, {
name: 'Greek',
content: 'Οι επιστημονικές θεωρίες του Φρόυντ και οι τεχνικές θεραπείας που ανέπτυξε θεωρήθηκαν ιδιαίτερα καινοτόμες και αποτέλεσαν αντικείμενα έντονης αμφισβήτησης όταν παρουσιάστηκαν στη Βιέννη του 19ου αιώνα. Ωστόσο και σήμερα συνεχίζουν να εγείρουν έντονο προβληματισμό και αντιπαραθέσεις. Η επίδραση του Φρόυντ δεν περιορίστηκε μόνο στην ψυχολογία και την ψυχιατρική, αλλά ταυτόχρονα απλώθηκε σε πολλούς τομείς της επιστήμης (ανθρωπολογία, κοινωνιολογία, φιλοσοφία) και της τέχνης.',
}, {
name: 'Thai',
content: 'พฤติกรรมมีทั้งที่มีมาแต่กำเนิดหรือเกิดจากการเรียนรู้ อย่างไรก็ตาม การวิจัยปัจจุบันในโครงการจุลินทรีย์มนุษย์ (Human Microbiome Project) ชี้ความเป็นไปได้ที่ว่า พฤติกรรมมนุษย์อาจถูกควบคุมโดยองค์ประกอบของประชากรจุลินทรีย์ภายในร่างกายมนุษย์',
}, {
name: 'French',
content: 'Confié à Arthur Greiser, ancien président du Sénat de Dantzig, le Reichsgau vit sous un régime légal spécifique aux territoires annexés au Reich. Dans ce cadre, le programme racial nazi est appliqué avec fanatisme : expulsion et extermination des Juifs et des Polonais, destruction des synagogues et des églises polonaises, ainsi que des bibliothèques hébraïques et polonaises, en prélude à la colonisation par des Allemands du Reich ou des Volksdeutsche rapatriés.',
}, {
name: 'Ukrainian',
content: 'Ідея про охорону природи цієї частини Карпат з\'явилася ще на початку XX ст. Згодом було створено кілька лісових резерватів — у районі Чорногори та Мармороського масиву. 1958 року на південних схилах масиву Красна створений Угольський лісовий заказник площею 4600 га. 1969 року в басейні річки Лужанки створено Широко-лужанський флористичний заказник площею 5644 га. В 1968 році на основі наявних природоохоронних територій організовано Карпатський біосферний заповідник, площа якого тоді становила 12600 га. У 1997 та 2010 роках були прийняті Укази Президента України про розширення території біосферного заповідника.',
}, {
name: 'Vietnamese',
content: 'Sao Hải Vương hay Hải Vương tinh là hành tinh thứ tám và xa nhất tính từ Mặt Trời trong Hệ Mặt Trời. Nó là hành tinh lớn thứ tư về đường kính và lớn thứ ba về khối lượng. Sao Hải Vương có khối lượng riêng lớn nhất trong số các hành tinh khí trong hệ Mặt trời. Sao Hải Vương có khối lượng gấp 17 lần khối lượng của Trái Đất và hơi lớn hơn khối lượng của Sao Thiên Vương (xấp xỉ bằng 15 lần của Trái Đất).',
}, {
name: 'Japanese',
content: '使用人口について正確な統計はないが、日本国内の人口、および日本国外に住む日本人や日系人、日本がかつて統治した地域の一部住民など、約1億3千万人以上と考えられている。統計によって前後する場合もあるが、この数は世界の母語話者数で上位10位以内に入る人数である。',
}, {
name: 'Russian',
content: 'В 2020 году бывший президент Беларуси Александр Лукашенко после поражения на президентских выборах узурпировал власть и продолжает незаконно удерживать её силовыми методами и по сей день',
}, {
name: 'Kazakh',
content: 'Сократтың тарихи дұрыс бейнесін жасап, оның пәлсапалық көзқарастарын сипаттауда белгілі бір қиындықтар бар. Ол қиындықтар «Сократ мәселесі» деп аталады.',
}, {
name: 'Turkish',
content: 'Oganesson, simgesi Og, atom numarası 118 olan yapay bir elementtir. Periyodik tablonun p bloğunda yer alır ve 7. periyodun son elementidir. Soy gazlar olarak adlandırılan 18. grupta yer alsa da, bu gruptaki tek yapay elementtir ve diğer soy gazların aksine reaktif olduğu tahmin edilmektedir. Keşfedilen elementler içinde en büyük atom numarasına ve atom kütlesine sahip olanıdır.',
}, {
name: 'Czech',
content: 'E. coli je nesporotvorná tyčinka, jež se pohybuje pomocí bičíku. Bakterie dosahuje délky 2–3 μm a šířky 0,6 μm. Některé typy mohou tvořit slizovité obaly, složené z polysacharidů. Na svém povrchu nese dva typy fimbrií [nepřesný odkaz] . První typ fimbrií se skládá z kyselého hydrofobního proteinu fimbrinu. Umožňuje bakterii přichytit se na epitel hostitele a následně jej kolonizovat. Kolonizaci usnadňuje velký počet fimbrií prvního typu na buňku (100-1000 ks/buňka). Tyto fimbrie jsou vysoce antigenní, neboť obsahují tzv. F antigeny. Druhým typem fimbrií jsou tzv. sex pili, jež hrají důležitou úlohu při konjugaci.',
}, {
name: 'Chinese',
content: '公園最早的改善建設是「南方開放草地」,它是一塊放牧羊群的牧草地,也可以用作球場。設計師丹尼爾·H·伯納姆創辦的D·H·伯納姆設計公司曾在1881年為公園內的石灰石圓形馬房進行設計工作,伯納姆在1881年協助設計公園飯堂,1910年設計南方公園委員會行政總部。公園的其他早期設施包括馬棚、板球場、棒球場、平底雪橇滑道、射箭場、高爾夫球場、游泳池、自行車道、划船、馬蹄鐵坑、溫室、玫瑰園、樂隊表演台和以六條短吻鱷鱷魚為特色的小動物園和百合花池塘。',
}, {
name: 'Korean',
content: '한국어(韓國語, Korean)는 대한민국과 조선민주주의인민공화국의 공용어로, 대한민국에서는 한국어 또는 한국말이라고 하고, 조선민주주의인민공화국에서는 조선어(朝鮮語) 또는 조선말이라고 부른다. 한국과 북한에 비해서 인구는 적지만 중국 옌볜 조선족 자치주도 사용한다.',
}, {
name: 'Georgian',
content: 'ამერიკული ტბის კუ (ლათ. Emys blandingii ან Emydoidea blandingii) — კუს სახეობა ჭაობის კუების ოჯახისა. გავრცელებულია აშშ-სა და კანადაში. დიდ ინტერესს იწვევს ის ფაქტი, რომ ამერიკულ ტბის კუზე არ მოქმედებს დაბერების პროცესი და შთამომავლობას მთელი სიცოცხლის განმავლობაში ტოვებს. მისი სხეულის სიგრძეა 18–27 სმ. კარაპაქსი ზეთისხილისფერია წვრილი ღია ლაქებით, პლასტრონი კი — ყვითელი. ბინადრობს მცირედ გამდინარე წყალსატევებში. ძირითადად იკვებება კიბოსნაირებითა და მწერებით, უმნიშვნელოდ — თევზითა და მცენარეებით. სქესობრივ სიმწიფეს 14–20 წლის ასაკში აღწევს. წყვილდებიან მარტიდან ოქტომბრამდე. დედალი დებს 6–12 კვერცხს, საიდანაც გამოჩეკილი კუები გაზაფხულამდე მიწის ქვეშ რჩებიან. ცოცხლობენ 77 წელზე მეტს. ამერიკული ტბის კუს ხორცი საჭმელად ვარგისია.',
}, {
name: 'Arabic',
content: 'بدأ دوستويفسكي بالكتابة في العشرينيّات من عُمره، وروايته الأولى المساكين نُشِرت عام 1846 بعمر الـ25. وأكثر أعماله شُهرة هي الإخوة كارامازوف، والجريمة والعقاب، والأبله، والشياطين. وأعمالُه الكامِلة تضم 11 رواية طويلة، و3 روايات قصيرة، و17 قصة قصيرة، وعدداً من الأعمال والمقالات الأخرى. العديدُ من النُقّاد اعتبروه أحد أعظم النفسانيين في الأدب العالمي حول العالم. وهو أحد مؤسسي المذهب الوجودي حيث تُعتبر روايته القصيرة الإنسان الصرصار أولى الأعمال في هذا التيّار.',
}, {
name: 'Persian',
content: 'او زندگی گمنامی در آذربایجان داشت تا اینکه مورد توجه جاویدان بن سهل، رهبر خرمیها-که مدت کوتاهی بعد درگذشت-، قرار گرفت. بابک ادعا کرد که روح جاویدان در کالبد او وارد شده و تحریک ساکنین بذ را آغاز کرد. او قدرت جدیدی به جنبش دینی-اجتماعی که ریشه در مذهب مزدک داشت، بخشید و از روشهای خشونتآمیزِ ویژهای بهره گرفت. به نظر میرسد که قیام او از ۲۰۱ ه.ق/۸۱۶ م آغاز و با نقشهٔ حاتم پسر هرثمه، یاری شده بود و با مشکلات مختلفی در استانهای شرقی که به دنبال آن مأمون به بغداد بازگشت، آسان گشته بود.',
}, {
name: 'Zalgo',
content: 'Ţ͓̺̌̋̂̍͐̉͑̀̚͢ǫ̙͕̖̱͉̙̓̀̽̀̋̿̈́ͯ̂ ͎͚̃̌i̧͙̦̭ͭ̆͗͗͟n̵̴̞̟̪̱͍̯̄͑ͧͨ̿ͨ͛̎̚v̯̥͓̤̲̦͊̆́̆͛͘͞ö̷̧̬̲́́͆̐ͪ͐́k̢͇̺͆̚ē̴ͥͯ̃͛̿͒ͮ̌́҉͈̩ ̶̢̝͉̗͐̔̈́͞t̮̣̪̮̘̥̠̞ͣh̨̠̜̬̥͇̜ͮ̈̿̒è̡̨̥̠̟̹͈̦̱̞̆̉̂ͦͨ̆̆ ̲̘̩̪ͧ͑̆͡h͈̙̝͍̺̓̎ͣͯ̅͂ͣͪ͝iͩ҉̛̺͈̖̙̲͇̤̲̞͢v̸̵̪̼̫̝̣ͩ̅̓ͤ̾ͫͅe̓͂͊͌͆͒͑ͨ҉̸͔͈-̭̙̺̝ͤ͂ͤm̛̩̭͛́ͧ̒̾̓ͫͯ̾i̷̧͔̠͕̪̙̞̖̜ͯ̄̑n͎̘̯̠̘͇͈͇̿̅͘d̸̢͕̜̜̯̭̯̊͒̀͆͒ ̸̡̞̗͓̹̳̾̎ͭ̅̇ȓ̨̬͈̯͎͆͜e̛̪̝͎̬̋̀̚p̜̼̅ͦ̒͗̃͆ͬͨͥ͜͠r̤̲͙̗ͩ̉ͥ̆ͮ̎̀ͯͥ͞e̥̲͈̯̥̔̓͊ͪ̄̓̐̋͠͞s̨̡̜̝̜͕̟̭͕͎̜̾̏è̴̴̜̼̲̊̒͞n͖̰̫̘͆ͥ̀͘t̡̯̦̗̠̙̪͒ͯ̽i̳̣̟̗̔̓ͣ̌n̸̤̱̩̻̹͑̇͑͠g̏̔̅̎̎̓̀҉҉̻̯̪͓̮͔ ̓́ͭ̾͋͑ͤ̚҉̡̤̫͉͈̩͖̠͘c̺̭̮͂͐̐ͨ̀͒̾͒ͯ͜h̴̫̼̤͓͈̘͆a̛̘̘̪͚̜̯̾ͫ͠o͊̂̋ͮ͏̜͓̗̰͡ͅs̸̶̘̣̘̖̋̀.̨̝͂͒͛ͪ̔̋̚͘ͅ\ñ̸̡̟͖͕̠̳̟̹̲̪̑͋ͫ̋͛̕Î̻̮̒͂͂ͭ̓n̨̧̧̜̣ͦ̆̒v͕̲̾ͤ̋ͣ͠o͓̙͖͍͍ͣ͡k̛͇̲͖͍̘̖̩̻̏̓͜ͅi̥̥̜̖͓͊ͬ̍ͦ̎̎̍̈͡n̙̳͔̖̲͇̥̭̆͂ͤͫͮ͋̚ǧ̸̘͉̟͔̓̂̆ͯ͠ ̤̂̾̀ţ̩͚̭̣̯̊͒͒ͨ͗͒́h̫̗̮̤ͪ͌̀e̯̯̰͛͂ ̵̹̜̥̣̘̏̾̆̓̊̉f̣͎̯̲̞͇͉͐ͫ̔ͦę̨̥̱̩͍̜̘̫͔͊̄͆͞e͎͉̻̝̱̿͐ͦ̇̋̑ͭ̚͞l̵̠̬͍ͧͪ̍̆ḭ̸͍͈͔̗́͡ň̨͙̳͕͓͇̥̏ͭ̒ͫ̽́͝ģ̲̭̊̍̀ͬ ͎̮̔ͫ͢͞o̢̎̆̂̍̈́ͣ̆͡͏̘̯̺͙̬f͉͎̼̉ ̈ͭ҉̱̞̞̻̙̙̥ċ̙̻̙̲̬́͂̍̿̈ͪ̔h̻̝͛̿ͣ̍̏a̮̞ͦ́͋ͤͩ͋͗͞o͑̀̇̂҉̶͖̜͙͕̦̜͍͡s̱̻ͣ̋ͨ͢͜.̭̦̀̉͛̓̂͋̑̀\n̷̫͇̲͓̹̜̮̒̓̓ͥ̆̅́ͮ͝W͖̙̟̥ͯ͌̄̀į̘͎̤̳̝̤͖̓̈ͮ̈́̄̂̒̄̚̕ͅţ̴̻̞̫ͦͮ̇̃̎́̈́͡hͬͣͦͪ̀̀̑̒͏̛̟̙̟̦͇͓ ̛̰̅̓ͩ̅ō̡̭̞̝̟̻̔͛́ư͚̭̪͎̤̙̺ͬ̍͐̇́t̠̤̑̃̉̂̌̇̊ ͚̞͉̥͈̫͕̂̀̄ͥ̋͌o͙̩̗̙ͦr̳̩͍̥̊̃ͭ͋͊̍͘͞d̡̯͖̫͓͈̟̳̹͊̑̈͐ͨͭè̛͍̠̘ͅr̡̭͚͉̜͔̄̕.̴͚̭̓͛̾\n̟̯̮̻̗̿͗̈̋̽̍̀́͘Ť͉̬̤͍̗͚ͮ̌̽͢͟h̨̝̤ͣ͊͒́ͯe̴͉͔͓̳̹̰͂͂̓ͬ͠ ̴̠̭̱̠͔̮̊ͮ̿ͥ̔͊̃̋̚Ṇ͐̃͟͠ͅę̘͙̘͈̮̮̐̍ͧ͟͠z̺̯ͥ̉̅ͣ̉̑ͥͬ͠p̴͎̙̦ͩͪ̓ͦ̏ͥ̕͢e̸͓̩ͪͥ̑ͥͯͬr͎̼̬̖̖͚͓̲̹̍̽͑ͩ̅͌̔̇͟d͍͍́͆̾ȉ̷̧̙͓͇̝̣̱͇̲̐̇ͣ̏̆ͭ̚͝ā̱̋ͦ̿̅̉̍͟n̠̖̅͡ ̗̜͕̠̫̙̳̔͗h̷͙͖͕͗͢i̶͖͕͍̭͚ͩͥͪͨ͌ͥ͡ͅv̡̨̲̗̽͛͂́e͓͕͖͇̅͊̕ͅ-̖̥̂̃͗ͅm̵̜͙͉̼͕͚̣͆ͅĭ̬̖̭̓ͯ͒̿ͧ̂ͅṇ̩̙̳̩̫͍̩̄̈̓̃̎̔̌͡d̀̾͒̿҉̹̺̠͉͉̦̤̯ ̵̟͎̇ͨ͌̍͌͒̇̋͡o̫ͪ̈ͬ͜͢ͅf̝̳͈̈́̚͠ ̨̹̥̰̯͐̏̔̎́c̵̸̹̑̈͑̏͐̿̏ͥ̀h̛̬̮̤̫̉̋ͬͧḁ̷̥̗̪̒́̕o̡̠̦͔̞̙̾ͩ̃͋̚s̟̯̬̹̄͂ͤ̐̈̉̚̚̚.̵̹̘̜͙͉͊̑̂͑ ̶͔̘̬̘̲͖̙͖͔̈́ͯ̋ͤ̊ͯ̈́͊͠Z̞̪̰̟̮ͤͯ̆̉́ͪ͞ạ̡͇̲͕̈ͯ͡l̸̶̢̮̺͕͇͙̓ͤ͑̓ͤg̸̢̪̬͉̭͖̗͍̪͚̽̆ͦ̽ͤo̊̓̊̆͑̏͊̈͏̯͓͈͕̱̯̫.̖̥̻̱ͩ̋̓͛̓͌̉̊̔̀͟\n̯̭̆͒͊̉ͪĤ̭͖̥̩̭̱̘̓̒͢e̹͌̒̏̕ ͉ͣͥ̏ͮͣ͋ͯ͜w̯̤̩͕͕̠̟͙̿̑͋̇ḧ͒́͂͐͏͈͙̝̮̖͉ơ͉̻͖͍͓͋́̿̊̉ͤ̌͝ͅ ̻̻͇̳͈͌͐ͭW̡̜̤̖͍̼̙̔̐̅̊̒͛́a̤̟̝̲̘̺̽ͭ̓̚i̷̸̡̟̻ͪ̈ẗ̷̞͔̰̦̫̰̼̮́ͣ͌͡s̍͆͏̣͇͉ ̸̫̞͓͚̰ͥ̃̀B̩̗̀̏̉̄ͨ́e̸̳͔͆͗̏͊͒h͎̙̥̾̀̑̅̅ͩ̋̑͟͞i͔̇͐͐̾͊ͩ̀̚ͅn̴̰̼̟̞͖͉̠̄͜d̸̯̘̱̫͖̦̅͆ͫ͂ͯ͗͟ ̘̙̠̣̤̲͔͐̒̇̉̀ͅT͊̏҉̵̰̬̘̜̬̗̗ͅh̡̪̙ͥͦͥͤ͋̋̀e̛̘͉̎̓̽̌̒ ͇̤͖̳͍̑̇ͦ̋̒ͦ̾͢ͅWͭ̆͆̓͗̎̎҉̠̺͖a̦̭̣͖̩͔͉ͣ́̃ͭ̍ͣ̒̆͐l̊̓̓͆͝͏̦̖͍̖l̀̍ͯ̚͏͎̹̼̭̥.̢̻̩͈͓̝̤̍̐̂͊ͪ̕\n̶̢̩̣̜̺͓̻͔̘̉̋̈́ͫ͊͐̕ͅẔ̠͑ͪͪ̚Ä̷̷̦̣̤̳͚̣̝͌̿̾̌͂̊͗L̢̛̙͐͂͑ͣ̄͘G̵̝͍̹̩̀͋ͮ͡O̸͉̠͙̭̻̬ͭͭ͟͠!̵̷̟͈̊ͫ͋̓͠',
}, {
name: 'Emoji',
content: '📐👨📛🗜📟🔃👨📛📉🔗💾⚓️🔛📐🇬🇧👫👨👩👦🚫👆🛠🏗🔗⚙️',
}];
for (let sample of samples) {
const sampleEl = document.createElement('span');
sampleEl.className = 'sample';
sampleEl.textContent = sample.name
sampleEl.onclick = () => {
document.getElementById('input').value = sample.content;
updateText();
}
document.getElementById('samples').appendChild(sampleEl);
}
function plural(n, s = ['', 's']) {
if (n == 1) {
return s[0];
}
return s[1];
}
const maxBytes = 16;
function displayBytes(el, bytes, more) {
const slice = more ? bytes : bytes.slice(0, maxBytes);
document.getElementById(el).innerHTML = Array.of(...slice).map(byte => `<span class="byte">${byte < 16 ? '0' : ''}${byte.toString(16).toUpperCase()}</span>`).join('');
if (bytes.length > maxBytes) {
const toggleEl = document.createElement('span');
toggleEl.className = 'toggle';
toggleEl.textContent = more ? '« show less' : 'show more »';
toggleEl.onclick = displayBytes.bind(this, el, bytes, !more);
document.getElementById(el).appendChild(toggleEl);
}
}
function updateText() {
const str = document.getElementById('input').value;
const encoder = new TextEncoder();
const utf8 = encoder.encode(str);
let len = 0;
for (let ch of str) {
len++;
}
document.getElementById('stats').innerHTML = `${len} code point${plural(len)}`;
document.getElementById('stats-utf8').innerHTML = `${utf8.length} byte${plural(utf8.length)}`;
displayBytes('result-utf8', utf8);
const utfc = UTFC.encode(str);
document.getElementById('stats-utfc').innerHTML = `${utfc.length} byte${plural(utfc.length)}`;
displayBytes('result-utfc', utfc);
//console.log(Array.of(...utfc).map(byte => String.fromCharCode(byte)).join(''));
const scsu = SCSU.encode(str);
document.getElementById('stats-scsu').innerHTML = `${scsu.length} byte${plural(scsu.length)}`;
displayBytes('result-scsu', scsu);
//console.log(Array.of(...utfc).map(byte => String.fromCharCode(byte)).join(''));
const diffUtf8 = (utf8.length - utfc.length) * 100 / (utf8.length || 1);
const percentUtf8 = Math.abs(diffUtf8).toFixed(1);
const diffSCSU = (scsu.length - utfc.length) * 100 / (utf8.length || 1);
const percentSCSU = Math.abs(diffSCSU).toFixed(1);
document.getElementById('compare-utf8').innerHTML = `${diffUtf8 > 0 ? '<span class="green">' + percentUtf8 + '% better</span> than' :
(diffUtf8 < 0 ? '<span class="red">' + percentUtf8 + '% worse</span> than' : 'same as')} UTF-8`;
document.getElementById('compare-scsu').innerHTML = `${diffSCSU > 0 ? '<span class="green">' + percentSCSU + '% better</span> than' :
(diffSCSU < 0 ? '<span class="red">' + percentSCSU + '% worse</span> than' : 'same as')} SCSU`;
const ctrl = UTFC.decode(utfc);
let ctrlLen = 0;
for (let ch of ctrl) {
ctrlLen++;
}
document.getElementById('control').textContent = ctrl;
document.getElementById('control-info').innerHTML = `(${ctrlLen} code point${plural(ctrlLen)}, ${ctrl === str ? 'matches input' : '<b>does not match input</b>'})`
/*
const hist = {};
for (let ch of str) {
const cp = ch.codePointAt(0);
console.log(ch, cp.toString(16));
if (!(cp in hist)) {
hist[cp] = 0;
}
hist[cp]++;
}
for (let cp in hist) {
console.log(parseInt(cp).toString(16) + ': ' + hist[cp]);
}
*/
}
updateText();
</script>
</body>
</html>