hayfork 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,132 @@
1
+ require "hayfork/binding"
2
+ require "hayfork/insert_sql"
3
+ require "hayfork/update_sql"
4
+ require "hayfork/delete_sql"
5
+
6
+ module Hayfork
7
+ class Statement
8
+ attr_reader :haystack, :relation, :value
9
+ attr_accessor :weight, :dictionary
10
+
11
+ def initialize(haystack, relation, field, options={})
12
+ @haystack = haystack
13
+ @relation = relation.all
14
+ @weight = options.fetch(:weight, Hayfork.default_weight) # TODO: validate weight
15
+ @dictionary = options.fetch(:dictionary, Hayfork.default_dictionary)
16
+ @attributes = {}.with_indifferent_access
17
+ @unnest = false
18
+ @unsearchable = false
19
+
20
+ case field
21
+ when Arel::Predications
22
+ @value = field
23
+ when String
24
+ @value = model.arel_table[field]
25
+ when Symbol
26
+ @value = model.arel_table[field.to_s]
27
+ when Hash
28
+ reflection = reflection_for(field.keys.first)
29
+ joins field.keys.first
30
+ @value = reflection.klass.arel_table[field.values.first.to_s]
31
+ else
32
+ fail ArgumentError, "Unrecognized value for `field`: #{field.inspect}"
33
+ end
34
+ end
35
+
36
+
37
+
38
+ def joins(join_value)
39
+ @relation = Hayfork.join(relation, join_value)
40
+ self
41
+ end
42
+
43
+ def where(where_value)
44
+ @relation = relation.where(where_value)
45
+ self
46
+ end
47
+
48
+ def merge(attrs = {})
49
+ attributes.merge! attrs.stringify_keys.except(
50
+ Hayfork::SEARCH_VECTOR,
51
+ Hayfork::TEXT,
52
+ Hayfork::SOURCE_TYPE,
53
+ Hayfork::SOURCE_ID)
54
+ self
55
+ end
56
+
57
+ def unsearchable
58
+ @unsearchable = true
59
+ self
60
+ end
61
+
62
+ def unnest
63
+ @unnest = true
64
+ self
65
+ end
66
+
67
+
68
+
69
+ def unsearchable?
70
+ @unsearchable == true
71
+ end
72
+
73
+ def unnest?
74
+ @unnest == true
75
+ end
76
+
77
+ def may_change_on_update?
78
+ !update.values_to_check_on_update.empty?
79
+ end
80
+
81
+
82
+
83
+ def insert
84
+ InsertSql.new(haystack, relation, bindings)
85
+ end
86
+
87
+ def update
88
+ UpdateSql.new(haystack, relation, bindings)
89
+ end
90
+
91
+ def delete
92
+ DeleteSql.new(haystack, relation, bindings)
93
+ end
94
+
95
+
96
+
97
+ def bindings
98
+ @bindings ||= (haystack.columns.each_with_object([]) do |column, bindings|
99
+ next if column.name == Hayfork::SEARCH_VECTOR && unsearchable?
100
+
101
+ value = attributes.fetch column.name do
102
+ case column.name
103
+ when Hayfork::SEARCH_RESULT_TYPE then model.name
104
+ when Hayfork::SEARCH_RESULT_ID then model.arel_table["id"]
105
+ when Hayfork::SEARCH_VECTOR, Hayfork::TEXT then self.value
106
+ when Hayfork::SOURCE_TYPE then self.value.relation.send(:type_caster).send(:types).name
107
+ when Hayfork::SOURCE_ID then self.value.relation["id"]
108
+ when Hayfork::FIELD then self.value.name
109
+ end
110
+ end
111
+
112
+ next unless value
113
+ value = model.arel_table[value] if value.is_a? Symbol
114
+ bindings.push Hayfork::Binding.new(self, column, value)
115
+ end)
116
+ end
117
+
118
+
119
+
120
+ private
121
+ attr_reader :attributes
122
+
123
+ def model
124
+ relation.model
125
+ end
126
+
127
+ def reflection_for(association)
128
+ Hayfork.reflection_for(model, association)
129
+ end
130
+
131
+ end
132
+ end
@@ -0,0 +1,78 @@
1
+ require "hayfork/statement"
2
+
3
+ module Hayfork
4
+ class StatementBuilder
5
+ attr_reader :row
6
+
7
+ def initialize(haystack, relation, attributes: {})
8
+ @haystack = haystack
9
+ @relation = relation
10
+ @attributes = attributes
11
+ @statements = []
12
+ @row = model.arel_table
13
+ end
14
+
15
+
16
+ def set(key, value)
17
+ @attributes.merge!(key => value)
18
+ end
19
+
20
+ def joins(join_value, &block) # reject SQL literals?
21
+ apply? Hayfork.join(relation, join_value), &block
22
+ end
23
+
24
+ def where(*args, &block) # reject SQL literals?
25
+ apply? relation.where(*args), &block
26
+ end
27
+
28
+
29
+ def insert(field, options={})
30
+ Statement.new(haystack, relation, field, options).tap do |statement|
31
+ statement.merge(attributes) if attributes.any?
32
+ statements << statement
33
+ end
34
+ end
35
+
36
+
37
+ def to_insert_sql(**args)
38
+ statements.map { |statement| " " << statement.insert.to_sql(**args) }.join.strip
39
+ end
40
+
41
+ def to_update_sql
42
+ updates = statements.select(&:may_change_on_update?)
43
+ return "-- nothing to update" if updates.empty?
44
+ updates.map { |statement| " " << statement.update.to_sql.lstrip }.join.strip
45
+ end
46
+
47
+ def to_delete_sql
48
+ statements.map { |statement| " " << statement.delete.to_sql }.join.strip
49
+ end
50
+
51
+
52
+ def to_a
53
+ statements
54
+ end
55
+
56
+ private
57
+ attr_reader :haystack, :relation, :statements, :attributes
58
+
59
+ def apply?(modified_relation, &block)
60
+ if block_given?
61
+ statements = StatementBuilder.new(haystack, modified_relation, attributes: attributes.dup)
62
+ if block.arity.zero?
63
+ statements.instance_eval(&block)
64
+ else
65
+ yield statements
66
+ end
67
+ @statements.concat statements.to_a
68
+ else
69
+ @relation = modified_relation
70
+ end
71
+ end
72
+
73
+ def model
74
+ relation.model
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1,17 @@
1
+ require "hayfork/statement_builder"
2
+
3
+ module Hayfork
4
+ class TriggerBuilder
5
+
6
+ def initialize(triggers)
7
+ @triggers = triggers
8
+ end
9
+
10
+ def foreach(model, options={}, &block)
11
+ statements = StatementBuilder.new(@triggers.haystack, model.unscope(:order, :select, :group, :having, :offset, :limit))
12
+ statements.instance_eval(&block)
13
+ @triggers << [model, statements, options]
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,76 @@
1
+ module Hayfork
2
+ class Triggers
3
+ attr_reader :haystack
4
+
5
+ def initialize(haystack)
6
+ @haystack = haystack
7
+ @_triggers = []
8
+ end
9
+
10
+ def <<(trigger)
11
+ _triggers << trigger
12
+ end
13
+
14
+ def create
15
+ _triggers.map { |args| psql_create_triggers_for(*args) }.join
16
+ end
17
+
18
+ def drop
19
+ _triggers.map { |model, _, options| psql_drop_triggers_for(model, options) }.join
20
+ end
21
+
22
+ def replace
23
+ [drop, create].join
24
+ end
25
+
26
+ def truncate
27
+ "TRUNCATE #{haystack.table_name};\n"
28
+ end
29
+
30
+ def rebuild
31
+ ([truncate] + _triggers.map { |args| psql_inserts_for(*args) }).join
32
+ end
33
+
34
+ private
35
+ attr_reader :_triggers
36
+
37
+ def psql_create_triggers_for(model, statements, options)
38
+ name = function_name(model, options)
39
+ <<~SQL
40
+ CREATE FUNCTION #{name}() RETURNS trigger AS $$
41
+ BEGIN
42
+ IF TG_OP = 'DELETE' THEN
43
+ #{statements.to_delete_sql}
44
+ RETURN OLD;
45
+ ELSIF TG_OP = 'UPDATE' THEN
46
+ #{statements.to_update_sql}
47
+ RETURN NEW;
48
+ ELSIF TG_OP = 'INSERT' THEN
49
+ #{statements.to_insert_sql}
50
+ RETURN NEW;
51
+ END IF;
52
+ RETURN NULL; -- result is ignored since this is an AFTER trigger
53
+ END;
54
+ $$ LANGUAGE plpgsql;
55
+ CREATE TRIGGER #{name}_trigger BEFORE INSERT OR UPDATE OR DELETE ON #{model.table_name}
56
+ FOR EACH ROW EXECUTE PROCEDURE #{name}();
57
+ SQL
58
+ end
59
+
60
+ def psql_inserts_for(model, statements, options)
61
+ "#{statements.to_insert_sql(from: false)}\n" if options.fetch(:rebuild, true)
62
+ end
63
+
64
+ def psql_drop_triggers_for(model, options)
65
+ name = function_name(model, options)
66
+ <<~SQL
67
+ DROP FUNCTION IF EXISTS #{name}() CASCADE;
68
+ SQL
69
+ end
70
+
71
+ def function_name(model, options)
72
+ options.fetch(:name, "maintain_#{model.table_name}_in_#{haystack.table_name}")
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,12 @@
1
+ module Hayfork
2
+ module Unaccent
3
+
4
+ def unaccent(string)
5
+ string.each_char.map { |char| RULES.fetch(char, char) }.join
6
+ end
7
+
8
+ # Use Postgres's own rules so this method's behavior matches Postgres's `unaccent` function.
9
+ RULES = Hash[File.read(File.expand_path("../../../postgres/unaccent.rules", __FILE__)).scan(/^([^\t]+)\t(.*)$/)].freeze
10
+
11
+ end
12
+ end
@@ -0,0 +1,112 @@
1
+ require "hayfork/delete_sql"
2
+ require "hayfork/insert_sql"
3
+
4
+ module Hayfork
5
+ class UpdateSql
6
+ attr_reader :haystack, :relation, :bindings
7
+
8
+ def initialize(haystack, relation, bindings)
9
+ @haystack = haystack
10
+ @relation = relation
11
+ @bindings = bindings
12
+ end
13
+
14
+ def to_sql
15
+ sql = values_to_check_on_update.map { |field| "OLD.#{field} IS DISTINCT FROM NEW.#{field}" }.join(" OR ")
16
+
17
+ <<-SQL
18
+ IF #{sql} THEN
19
+ #{delete.to_sql.strip}
20
+ #{insert.to_sql.strip}
21
+ END IF;
22
+ SQL
23
+ end
24
+ alias to_s to_sql
25
+
26
+ def model
27
+ relation.model
28
+ end
29
+
30
+ def values_to_check_on_update
31
+ foreign_keys_by_table_name = {}
32
+ (relation.joins_values + relation.left_outer_joins_values).each do |join_value|
33
+ if join_value.is_a? String
34
+ fail NotImplementedError, "Unhandled literal join: #{join_value.inspect}"
35
+ end
36
+
37
+ reflection = reflection_for(join_value)
38
+ table_name = reflection.table_name
39
+ reflection = reflection.through_reflection if reflection.is_a?(ActiveRecord::Reflection::ThroughReflection)
40
+
41
+ case reflection
42
+ when ActiveRecord::Reflection::BelongsToReflection
43
+ foreign_keys_by_table_name[table_name] = [ reflection.foreign_key.to_s ]
44
+ when ActiveRecord::Reflection::HasManyReflection
45
+ foreign_keys_by_table_name[table_name] = [] # assume identity keys won't change
46
+ when ActiveRecord::Reflection::HasAndBelongsToManyReflection
47
+ foreign_keys_by_table_name[reflection.join_table] = [] # assume identity keys won't change
48
+ foreign_keys_by_table_name[table_name] = [] # assume identity keys won't change
49
+ else
50
+ fail NotImplementedError, "Unhandled reflection: #{reflection.class} (join_value: #{join_value.inspect})"
51
+ end
52
+ end
53
+
54
+
55
+ values_being_written = bindings.pluck(:raw_value) + predicate_fields
56
+ values_to_check_on_update = Set.new
57
+
58
+ values_being_written.each do |value|
59
+ next if value.is_a?(String) # constant
60
+ if value.relation.name == relation.table_name
61
+ values_to_check_on_update << value.name.to_s
62
+ else
63
+ # The value isn't a field of the current record but of a joined record.
64
+ # That record hasn't changed so we don't care about its value; but we
65
+ # do care whether this record's foreign keys have changed (which would
66
+ # cause it to be associated with a different joined record).
67
+ values_to_check_on_update.merge foreign_keys_by_table_name.fetch(value.relation.name)
68
+ end
69
+ end
70
+
71
+ values_to_check_on_update - model.readonly_attributes
72
+ end
73
+
74
+ private
75
+
76
+ def insert
77
+ InsertSql.new(haystack, relation, bindings)
78
+ end
79
+
80
+ def delete
81
+ DeleteSql.new(haystack, relation, bindings)
82
+ end
83
+
84
+ def predicate_fields
85
+ relation.where_clause.send(:predicates).map(&method(:field_from_predicate))
86
+ end
87
+
88
+ def field_from_predicate(predicate)
89
+ case predicate
90
+ when Arel::Nodes::Between,
91
+ Arel::Nodes::Equality,
92
+ Arel::Nodes::GreaterThan,
93
+ Arel::Nodes::GreaterThanOrEqual,
94
+ Arel::Nodes::In,
95
+ Arel::Nodes::LessThan,
96
+ Arel::Nodes::LessThanOrEqual,
97
+ Arel::Nodes::NotEqual,
98
+ Arel::Nodes::NotIn
99
+ field_from_predicate(predicate.left)
100
+ when Arel::Attributes::Attribute
101
+ predicate
102
+ else
103
+ fail NotImplementedError, "Unhandled predicate: #{predicate.class}: #{predicate.inspect}"
104
+ end
105
+ end
106
+
107
+ def reflection_for(association)
108
+ Hayfork.reflection_for(model, association)
109
+ end
110
+
111
+ end
112
+ end
@@ -0,0 +1,3 @@
1
+ module Hayfork
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,1049 @@
1
+ © (C)
2
+ « <<
3
+ ­ -
4
+ ® (R)
5
+ » >>
6
+ ¼ 1/4
7
+ ½ 1/2
8
+ ¾ 3/4
9
+ À A
10
+ Á A
11
+ Â A
12
+ Ã A
13
+ Ä A
14
+ Å A
15
+ Æ AE
16
+ Ç C
17
+ È E
18
+ É E
19
+ Ê E
20
+ Ë E
21
+ Ì I
22
+ Í I
23
+ Î I
24
+ Ï I
25
+ Ð D
26
+ Ñ N
27
+ Ò O
28
+ Ó O
29
+ Ô O
30
+ Õ O
31
+ Ö O
32
+ × *
33
+ Ø O
34
+ Ù U
35
+ Ú U
36
+ Û U
37
+ Ü U
38
+ Ý Y
39
+ Þ TH
40
+ ß ss
41
+ à a
42
+ á a
43
+ â a
44
+ ã a
45
+ ä a
46
+ å a
47
+ æ ae
48
+ ç c
49
+ è e
50
+ é e
51
+ ê e
52
+ ë e
53
+ ì i
54
+ í i
55
+ î i
56
+ ï i
57
+ ð d
58
+ ñ n
59
+ ò o
60
+ ó o
61
+ ô o
62
+ õ o
63
+ ö o
64
+ ÷ /
65
+ ø o
66
+ ù u
67
+ ú u
68
+ û u
69
+ ü u
70
+ ý y
71
+ þ th
72
+ ÿ y
73
+ Ā A
74
+ ā a
75
+ Ă A
76
+ ă a
77
+ Ą A
78
+ ą a
79
+ Ć C
80
+ ć c
81
+ Ĉ C
82
+ ĉ c
83
+ Ċ C
84
+ ċ c
85
+ Č C
86
+ č c
87
+ Ď D
88
+ ď d
89
+ Đ D
90
+ đ d
91
+ Ē E
92
+ ē e
93
+ Ĕ E
94
+ ĕ e
95
+ Ė E
96
+ ė e
97
+ Ę E
98
+ ę e
99
+ Ě E
100
+ ě e
101
+ Ĝ G
102
+ ĝ g
103
+ Ğ G
104
+ ğ g
105
+ Ġ G
106
+ ġ g
107
+ Ģ G
108
+ ģ g
109
+ Ĥ H
110
+ ĥ h
111
+ Ħ H
112
+ ħ h
113
+ Ĩ I
114
+ ĩ i
115
+ Ī I
116
+ ī i
117
+ Ĭ I
118
+ ĭ i
119
+ Į I
120
+ į i
121
+ İ I
122
+ ı i
123
+ IJ IJ
124
+ ij ij
125
+ Ĵ J
126
+ ĵ j
127
+ Ķ K
128
+ ķ k
129
+ ĸ q
130
+ Ĺ L
131
+ ĺ l
132
+ Ļ L
133
+ ļ l
134
+ Ľ L
135
+ ľ l
136
+ Ŀ L
137
+ ŀ l
138
+ Ł L
139
+ ł l
140
+ Ń N
141
+ ń n
142
+ Ņ N
143
+ ņ n
144
+ Ň N
145
+ ň n
146
+ ʼn 'n
147
+ Ŋ N
148
+ ŋ n
149
+ Ō O
150
+ ō o
151
+ Ŏ O
152
+ ŏ o
153
+ Ő O
154
+ ő o
155
+ Œ OE
156
+ œ oe
157
+ Ŕ R
158
+ ŕ r
159
+ Ŗ R
160
+ ŗ r
161
+ Ř R
162
+ ř r
163
+ Ś S
164
+ ś s
165
+ Ŝ S
166
+ ŝ s
167
+ Ş S
168
+ ş s
169
+ Š S
170
+ š s
171
+ Ţ T
172
+ ţ t
173
+ Ť T
174
+ ť t
175
+ Ŧ T
176
+ ŧ t
177
+ Ũ U
178
+ ũ u
179
+ Ū U
180
+ ū u
181
+ Ŭ U
182
+ ŭ u
183
+ Ů U
184
+ ů u
185
+ Ű U
186
+ ű u
187
+ Ų U
188
+ ų u
189
+ Ŵ W
190
+ ŵ w
191
+ Ŷ Y
192
+ ŷ y
193
+ Ÿ Y
194
+ Ź Z
195
+ ź z
196
+ Ż Z
197
+ ż z
198
+ Ž Z
199
+ ž z
200
+ ſ s
201
+ ƀ b
202
+ Ɓ B
203
+ Ƃ B
204
+ ƃ b
205
+ Ƈ C
206
+ ƈ c
207
+ Ɖ D
208
+ Ɗ D
209
+ Ƌ D
210
+ ƌ d
211
+ Ɛ E
212
+ Ƒ F
213
+ ƒ f
214
+ Ɠ G
215
+ ƕ hv
216
+ Ɩ I
217
+ Ɨ I
218
+ Ƙ K
219
+ ƙ k
220
+ ƚ l
221
+ Ɲ N
222
+ ƞ n
223
+ Ơ O
224
+ ơ o
225
+ Ƣ OI
226
+ ƣ oi
227
+ Ƥ P
228
+ ƥ p
229
+ ƫ t
230
+ Ƭ T
231
+ ƭ t
232
+ Ʈ T
233
+ Ư U
234
+ ư u
235
+ Ʋ V
236
+ Ƴ Y
237
+ ƴ y
238
+ Ƶ Z
239
+ ƶ z
240
+ DŽ DZ
241
+ Dž Dz
242
+ dž dz
243
+ LJ LJ
244
+ Lj Lj
245
+ lj lj
246
+ NJ NJ
247
+ Nj Nj
248
+ nj nj
249
+ Ǎ A
250
+ ǎ a
251
+ Ǐ I
252
+ ǐ i
253
+ Ǒ O
254
+ ǒ o
255
+ Ǔ U
256
+ ǔ u
257
+ Ǥ G
258
+ ǥ g
259
+ Ǧ G
260
+ ǧ g
261
+ Ǩ K
262
+ ǩ k
263
+ Ǫ O
264
+ ǫ o
265
+ ǰ j
266
+ DZ DZ
267
+ Dz Dz
268
+ dz dz
269
+ Ǵ G
270
+ ǵ g
271
+ Ǹ N
272
+ ǹ n
273
+ Ȁ A
274
+ ȁ a
275
+ Ȃ A
276
+ ȃ a
277
+ Ȅ E
278
+ ȅ e
279
+ Ȇ E
280
+ ȇ e
281
+ Ȉ I
282
+ ȉ i
283
+ Ȋ I
284
+ ȋ i
285
+ Ȍ O
286
+ ȍ o
287
+ Ȏ O
288
+ ȏ o
289
+ Ȑ R
290
+ ȑ r
291
+ Ȓ R
292
+ ȓ r
293
+ Ȕ U
294
+ ȕ u
295
+ Ȗ U
296
+ ȗ u
297
+ Ș S
298
+ ș s
299
+ Ț T
300
+ ț t
301
+ Ȟ H
302
+ ȟ h
303
+ ȡ d
304
+ Ȥ Z
305
+ ȥ z
306
+ Ȧ A
307
+ ȧ a
308
+ Ȩ E
309
+ ȩ e
310
+ Ȯ O
311
+ ȯ o
312
+ Ȳ Y
313
+ ȳ y
314
+ ȴ l
315
+ ȵ n
316
+ ȶ t
317
+ ȷ j
318
+ ȸ db
319
+ ȹ qp
320
+ Ⱥ A
321
+ Ȼ C
322
+ ȼ c
323
+ Ƚ L
324
+ Ⱦ T
325
+ ȿ s
326
+ ɀ z
327
+ Ƀ B
328
+ Ʉ U
329
+ Ɇ E
330
+ ɇ e
331
+ Ɉ J
332
+ ɉ j
333
+ Ɍ R
334
+ ɍ r
335
+ Ɏ Y
336
+ ɏ y
337
+ ɓ b
338
+ ɕ c
339
+ ɖ d
340
+ ɗ d
341
+ ɛ e
342
+ ɟ j
343
+ ɠ g
344
+ ɡ g
345
+ ɢ G
346
+ ɦ h
347
+ ɧ h
348
+ ɨ i
349
+ ɪ I
350
+ ɫ l
351
+ ɬ l
352
+ ɭ l
353
+ ɱ m
354
+ ɲ n
355
+ ɳ n
356
+ ɴ N
357
+ ɶ OE
358
+ ɼ r
359
+ ɽ r
360
+ ɾ r
361
+ ʀ R
362
+ ʂ s
363
+ ʈ t
364
+ ʉ u
365
+ ʋ v
366
+ ʏ Y
367
+ ʐ z
368
+ ʑ z
369
+ ʙ B
370
+ ʛ G
371
+ ʜ H
372
+ ʝ j
373
+ ʟ L
374
+ ʠ q
375
+ ʣ dz
376
+ ʥ dz
377
+ ʦ ts
378
+ ʪ ls
379
+ ʫ lz
380
+ Ё Е
381
+ ё е
382
+ ᴀ A
383
+ ᴁ AE
384
+ ᴃ B
385
+ ᴄ C
386
+ ᴅ D
387
+ ᴆ D
388
+ ᴇ E
389
+ ᴊ J
390
+ ᴋ K
391
+ ᴌ L
392
+ ᴍ M
393
+ ᴏ O
394
+ ᴘ P
395
+ ᴛ T
396
+ ᴜ U
397
+ ᴠ V
398
+ ᴡ W
399
+ ᴢ Z
400
+ ᵫ ue
401
+ ᵬ b
402
+ ᵭ d
403
+ ᵮ f
404
+ ᵯ m
405
+ ᵰ n
406
+ ᵱ p
407
+ ᵲ r
408
+ ᵳ r
409
+ ᵴ s
410
+ ᵵ t
411
+ ᵶ z
412
+ ᵺ th
413
+ ᵻ I
414
+ ᵽ p
415
+ ᵾ U
416
+ ᶀ b
417
+ ᶁ d
418
+ ᶂ f
419
+ ᶃ g
420
+ ᶄ k
421
+ ᶅ l
422
+ ᶆ m
423
+ ᶇ n
424
+ ᶈ p
425
+ ᶉ r
426
+ ᶊ s
427
+ ᶌ v
428
+ ᶍ x
429
+ ᶎ z
430
+ ᶏ a
431
+ ᶑ d
432
+ ᶒ e
433
+ ᶓ e
434
+ ᶖ i
435
+ ᶙ u
436
+ Ḁ A
437
+ ḁ a
438
+ Ḃ B
439
+ ḃ b
440
+ Ḅ B
441
+ ḅ b
442
+ Ḇ B
443
+ ḇ b
444
+ Ḋ D
445
+ ḋ d
446
+ Ḍ D
447
+ ḍ d
448
+ Ḏ D
449
+ ḏ d
450
+ Ḑ D
451
+ ḑ d
452
+ Ḓ D
453
+ ḓ d
454
+ Ḙ E
455
+ ḙ e
456
+ Ḛ E
457
+ ḛ e
458
+ Ḟ F
459
+ ḟ f
460
+ Ḡ G
461
+ ḡ g
462
+ Ḣ H
463
+ ḣ h
464
+ Ḥ H
465
+ ḥ h
466
+ Ḧ H
467
+ ḧ h
468
+ Ḩ H
469
+ ḩ h
470
+ Ḫ H
471
+ ḫ h
472
+ Ḭ I
473
+ ḭ i
474
+ Ḱ K
475
+ ḱ k
476
+ Ḳ K
477
+ ḳ k
478
+ Ḵ K
479
+ ḵ k
480
+ Ḷ L
481
+ ḷ l
482
+ Ḻ L
483
+ ḻ l
484
+ Ḽ L
485
+ ḽ l
486
+ Ḿ M
487
+ ḿ m
488
+ Ṁ M
489
+ ṁ m
490
+ Ṃ M
491
+ ṃ m
492
+ Ṅ N
493
+ ṅ n
494
+ Ṇ N
495
+ ṇ n
496
+ Ṉ N
497
+ ṉ n
498
+ Ṋ N
499
+ ṋ n
500
+ Ṕ P
501
+ ṕ p
502
+ Ṗ P
503
+ ṗ p
504
+ Ṙ R
505
+ ṙ r
506
+ Ṛ R
507
+ ṛ r
508
+ Ṟ R
509
+ ṟ r
510
+ Ṡ S
511
+ ṡ s
512
+ Ṣ S
513
+ ṣ s
514
+ Ṫ T
515
+ ṫ t
516
+ Ṭ T
517
+ ṭ t
518
+ Ṯ T
519
+ ṯ t
520
+ Ṱ T
521
+ ṱ t
522
+ Ṳ U
523
+ ṳ u
524
+ Ṵ U
525
+ ṵ u
526
+ Ṷ U
527
+ ṷ u
528
+ Ṽ V
529
+ ṽ v
530
+ Ṿ V
531
+ ṿ v
532
+ Ẁ W
533
+ ẁ w
534
+ Ẃ W
535
+ ẃ w
536
+ Ẅ W
537
+ ẅ w
538
+ Ẇ W
539
+ ẇ w
540
+ Ẉ W
541
+ ẉ w
542
+ Ẋ X
543
+ ẋ x
544
+ Ẍ X
545
+ ẍ x
546
+ Ẏ Y
547
+ ẏ y
548
+ Ẑ Z
549
+ ẑ z
550
+ Ẓ Z
551
+ ẓ z
552
+ Ẕ Z
553
+ ẕ z
554
+ ẖ h
555
+ ẗ t
556
+ ẘ w
557
+ ẙ y
558
+ ẚ a
559
+ ẜ s
560
+ ẝ s
561
+ ẞ SS
562
+ Ạ A
563
+ ạ a
564
+ Ả A
565
+ ả a
566
+ Ẹ E
567
+ ẹ e
568
+ Ẻ E
569
+ ẻ e
570
+ Ẽ E
571
+ ẽ e
572
+ Ỉ I
573
+ ỉ i
574
+ Ị I
575
+ ị i
576
+ Ọ O
577
+ ọ o
578
+ Ỏ O
579
+ ỏ o
580
+ Ụ U
581
+ ụ u
582
+ Ủ U
583
+ ủ u
584
+ Ỳ Y
585
+ ỳ y
586
+ Ỵ Y
587
+ ỵ y
588
+ Ỷ Y
589
+ ỷ y
590
+ Ỹ Y
591
+ ỹ y
592
+ Ỻ LL
593
+ ỻ ll
594
+ Ỽ V
595
+ ỽ v
596
+ Ỿ Y
597
+ ỿ y
598
+ ‐ -
599
+ ‑ -
600
+ ‒ -
601
+ – -
602
+ — -
603
+ ― -
604
+ ‖ ||
605
+ ‘ '
606
+ ’ '
607
+ ‚ ,
608
+ ‛ '
609
+ “ "
610
+ ” "
611
+ „ ,,
612
+ ‟ "
613
+ ․ .
614
+ ‥ ..
615
+ … ...
616
+ ′ '
617
+ ″ "
618
+ ‹ <
619
+ › >
620
+ ‼ !!
621
+ ⁄ /
622
+ ⁅ [
623
+ ⁆ ]
624
+ ⁇ ??
625
+ ⁈ ?!
626
+ ⁉ !?
627
+ ⁎ *
628
+ ₠ CE
629
+ ₢ Cr
630
+ ₣ Fr.
631
+ ₤ L.
632
+ ₧ Pts
633
+ ₹ Rs
634
+ ₺ TL
635
+ ℀ a/c
636
+ ℁ a/s
637
+ ℂ C
638
+ ℃ °C
639
+ ℅ c/o
640
+ ℆ c/u
641
+ ℉ °F
642
+ ℊ g
643
+ ℋ H
644
+ ℌ x
645
+ ℍ H
646
+ ℎ h
647
+ ℐ I
648
+ ℑ I
649
+ ℒ L
650
+ ℓ l
651
+ ℕ N
652
+ № No
653
+ ℗ (P)
654
+ ℙ P
655
+ ℚ Q
656
+ ℛ R
657
+ ℜ R
658
+ ℝ R
659
+ ℞ Rx
660
+ ℡ TEL
661
+ ℤ Z
662
+ ℨ Z
663
+ ℬ B
664
+ ℭ C
665
+ ℯ e
666
+ ℰ E
667
+ ℱ F
668
+ ℳ M
669
+ ℴ o
670
+ ℹ i
671
+ ℻ FAX
672
+ ⅅ D
673
+ ⅆ d
674
+ ⅇ e
675
+ ⅈ i
676
+ ⅉ j
677
+ ⅓ 1/3
678
+ ⅔ 2/3
679
+ ⅕ 1/5
680
+ ⅖ 2/5
681
+ ⅗ 3/5
682
+ ⅘ 4/5
683
+ ⅙ 1/6
684
+ ⅚ 5/6
685
+ ⅛ 1/8
686
+ ⅜ 3/8
687
+ ⅝ 5/8
688
+ ⅞ 7/8
689
+ ⅟ 1/
690
+ Ⅰ I
691
+ Ⅱ II
692
+ Ⅲ III
693
+ Ⅳ IV
694
+ Ⅴ V
695
+ Ⅵ VI
696
+ Ⅶ VII
697
+ Ⅷ VIII
698
+ Ⅸ IX
699
+ Ⅹ X
700
+ Ⅺ XI
701
+ Ⅻ XII
702
+ Ⅼ L
703
+ Ⅽ C
704
+ Ⅾ D
705
+ Ⅿ M
706
+ ⅰ i
707
+ ⅱ ii
708
+ ⅲ iii
709
+ ⅳ iv
710
+ ⅴ v
711
+ ⅵ vi
712
+ ⅶ vii
713
+ ⅷ viii
714
+ ⅸ ix
715
+ ⅹ x
716
+ ⅺ xi
717
+ ⅻ xii
718
+ ⅼ l
719
+ ⅽ c
720
+ ⅾ d
721
+ ⅿ m
722
+ − -
723
+ ∕ /
724
+ ∖ \
725
+ ∣ |
726
+ ∥ ||
727
+ ≪ <<
728
+ ≫ >>
729
+ ⑴ (1)
730
+ ⑵ (2)
731
+ ⑶ (3)
732
+ ⑷ (4)
733
+ ⑸ (5)
734
+ ⑹ (6)
735
+ ⑺ (7)
736
+ ⑻ (8)
737
+ ⑼ (9)
738
+ ⑽ (10)
739
+ ⑾ (11)
740
+ ⑿ (12)
741
+ ⒀ (13)
742
+ ⒁ (14)
743
+ ⒂ (15)
744
+ ⒃ (16)
745
+ ⒄ (17)
746
+ ⒅ (18)
747
+ ⒆ (19)
748
+ ⒇ (20)
749
+ ⒈ 1.
750
+ ⒉ 2.
751
+ ⒊ 3.
752
+ ⒋ 4.
753
+ ⒌ 5.
754
+ ⒍ 6.
755
+ ⒎ 7.
756
+ ⒏ 8.
757
+ ⒐ 9.
758
+ ⒑ 10.
759
+ ⒒ 11.
760
+ ⒓ 12.
761
+ ⒔ 13.
762
+ ⒕ 14.
763
+ ⒖ 15.
764
+ ⒗ 16.
765
+ ⒘ 17.
766
+ ⒙ 18.
767
+ ⒚ 19.
768
+ ⒛ 20.
769
+ ⒜ (a)
770
+ ⒝ (b)
771
+ ⒞ (c)
772
+ ⒟ (d)
773
+ ⒠ (e)
774
+ ⒡ (f)
775
+ ⒢ (g)
776
+ ⒣ (h)
777
+ ⒤ (i)
778
+ ⒥ (j)
779
+ ⒦ (k)
780
+ ⒧ (l)
781
+ ⒨ (m)
782
+ ⒩ (n)
783
+ ⒪ (o)
784
+ ⒫ (p)
785
+ ⒬ (q)
786
+ ⒭ (r)
787
+ ⒮ (s)
788
+ ⒯ (t)
789
+ ⒰ (u)
790
+ ⒱ (v)
791
+ ⒲ (w)
792
+ ⒳ (x)
793
+ ⒴ (y)
794
+ ⒵ (z)
795
+ ⦅ ((
796
+ ⦆ ))
797
+ ⩴ ::=
798
+ ⩵ ==
799
+ ⩶ ===
800
+ 、 ,
801
+ 。 .
802
+ 〇 0
803
+ 〈 <
804
+ 〉 >
805
+ 《 <<
806
+ 》 >>
807
+ 〔 [
808
+ 〕 ]
809
+ 〘 [
810
+ 〙 ]
811
+ 〚 [
812
+ 〛 ]
813
+ 〝 "
814
+ 〞 "
815
+ ㍱ hPa
816
+ ㍲ da
817
+ ㍳ AU
818
+ ㍴ bar
819
+ ㍵ oV
820
+ ㍶ pc
821
+ ㍷ dm
822
+ ㍺ IU
823
+ ㎀ pA
824
+ ㎁ nA
825
+ ㎃ mA
826
+ ㎄ kA
827
+ ㎅ KB
828
+ ㎆ MB
829
+ ㎇ GB
830
+ ㎈ cal
831
+ ㎉ kcal
832
+ ㎊ pF
833
+ ㎋ nF
834
+ ㎎ mg
835
+ ㎏ kg
836
+ ㎐ Hz
837
+ ㎑ kHz
838
+ ㎒ MHz
839
+ ㎓ GHz
840
+ ㎔ THz
841
+ ㎙ fm
842
+ ㎚ nm
843
+ ㎜ mm
844
+ ㎝ cm
845
+ ㎞ km
846
+ ㎧ m/s
847
+ ㎩ Pa
848
+ ㎪ kPa
849
+ ㎫ MPa
850
+ ㎬ GPa
851
+ ㎭ rad
852
+ ㎮ rad/s
853
+ ㎰ ps
854
+ ㎱ ns
855
+ ㎳ ms
856
+ ㎴ pV
857
+ ㎵ nV
858
+ ㎷ mV
859
+ ㎸ kV
860
+ ㎹ MV
861
+ ㎺ pW
862
+ ㎻ nW
863
+ ㎽ mW
864
+ ㎾ kW
865
+ ㎿ MW
866
+ ㏂ a.m.
867
+ ㏃ Bq
868
+ ㏄ cc
869
+ ㏅ cd
870
+ ㏆ C/kg
871
+ ㏇ Co.
872
+ ㏈ dB
873
+ ㏉ Gy
874
+ ㏊ ha
875
+ ㏋ HP
876
+ ㏌ in
877
+ ㏍ KK
878
+ ㏎ KM
879
+ ㏏ kt
880
+ ㏐ lm
881
+ ㏑ ln
882
+ ㏒ log
883
+ ㏓ lx
884
+ ㏔ mb
885
+ ㏕ mil
886
+ ㏖ mol
887
+ ㏗ pH
888
+ ㏘ p.m.
889
+ ㏙ PPM
890
+ ㏚ PR
891
+ ㏛ sr
892
+ ㏜ Sv
893
+ ㏝ Wb
894
+ ㏞ V/m
895
+ ㏟ A/m
896
+ ff ff
897
+ fi fi
898
+ fl fl
899
+ ffi ffi
900
+ ffl ffl
901
+ ſt st
902
+ st st
903
+ ︐ ,
904
+ ︑ ,
905
+ ︒ .
906
+ ︓ :
907
+ ︔ ;
908
+ ︕ !
909
+ ︖ ?
910
+ ︙ ...
911
+ ︰ ..
912
+ ︱ -
913
+ ︲ -
914
+ ︵ (
915
+ ︶ )
916
+ ︷ {
917
+ ︸ }
918
+ ︹ [
919
+ ︺ ]
920
+ ︽ <<
921
+ ︾ >>
922
+ ︿ <
923
+ ﹀ >
924
+ ﹇ [
925
+ ﹈ ]
926
+ ﹐ ,
927
+ ﹑ ,
928
+ ﹒ .
929
+ ﹔ ;
930
+ ﹕ :
931
+ ﹖ ?
932
+ ﹗ !
933
+ ﹘ -
934
+ ﹙ (
935
+ ﹚ )
936
+ ﹛ {
937
+ ﹜ }
938
+ ﹝ [
939
+ ﹞ ]
940
+ ﹟ #
941
+ ﹠ &
942
+ ﹡ *
943
+ ﹢ +
944
+ ﹣ -
945
+ ﹤ <
946
+ ﹥ >
947
+ ﹦ =
948
+ ﹨ \
949
+ ﹩ $
950
+ ﹪ %
951
+ ﹫ @
952
+ ! !
953
+ " "
954
+ # #
955
+ $ $
956
+ % %
957
+ & &
958
+ ' '
959
+ ( (
960
+ ) )
961
+ * *
962
+ + +
963
+ , ,
964
+ - -
965
+ . .
966
+ / /
967
+ 0 0
968
+ 1 1
969
+ 2 2
970
+ 3 3
971
+ 4 4
972
+ 5 5
973
+ 6 6
974
+ 7 7
975
+ 8 8
976
+ 9 9
977
+ : :
978
+ ; ;
979
+ < <
980
+ = =
981
+ > >
982
+ ? ?
983
+ @ @
984
+ A A
985
+ B B
986
+ C C
987
+ D D
988
+ E E
989
+ F F
990
+ G G
991
+ H H
992
+ I I
993
+ J J
994
+ K K
995
+ L L
996
+ M M
997
+ N N
998
+ O O
999
+ P P
1000
+ Q Q
1001
+ R R
1002
+ S S
1003
+ T T
1004
+ U U
1005
+ V V
1006
+ W W
1007
+ X X
1008
+ Y Y
1009
+ Z Z
1010
+ [ [
1011
+ \ \
1012
+ ] ]
1013
+ ^ ^
1014
+ _ _
1015
+ ` `
1016
+ a a
1017
+ b b
1018
+ c c
1019
+ d d
1020
+ e e
1021
+ f f
1022
+ g g
1023
+ h h
1024
+ i i
1025
+ j j
1026
+ k k
1027
+ l l
1028
+ m m
1029
+ n n
1030
+ o o
1031
+ p p
1032
+ q q
1033
+ r r
1034
+ s s
1035
+ t t
1036
+ u u
1037
+ v v
1038
+ w w
1039
+ x x
1040
+ y y
1041
+ z z
1042
+ { {
1043
+ | |
1044
+ } }
1045
+ ~ ~
1046
+ ⦅ ((
1047
+ ⦆ ))
1048
+ 。 .
1049
+ 、 ,