diff --git a/src/reason-parser/dune b/src/reason-parser/dune index 98fe54c52..b65caf989 100644 --- a/src/reason-parser/dune +++ b/src/reason-parser/dune @@ -5,13 +5,15 @@ (rule (targets ocaml_util.ml) - (deps ../generate/select.exe ocaml_util.ml-4.10 ocaml_util.ml-4.09 ocaml_util.ml-4.08 - ocaml_util.ml-4.07 ocaml_util.ml-4.06 ocaml_util.ml-default) + (deps ../generate/select.exe ocaml_util.ml-4.10 ocaml_util.ml-4.09 + ocaml_util.ml-4.08 ocaml_util.ml-4.07 ocaml_util.ml-4.06 + ocaml_util.ml-default) (action (with-stdout-to %{targets} - (run ../generate/select.exe ocaml_util.ml-4.10 ocaml_util.ml-4.09 ocaml_util.ml-4.08 - ocaml_util.ml-4.07 ocaml_util.ml-4.06 ocaml_util.ml-default)))) + (run ../generate/select.exe ocaml_util.ml-4.10 ocaml_util.ml-4.09 + ocaml_util.ml-4.08 ocaml_util.ml-4.07 ocaml_util.ml-4.06 + ocaml_util.ml-default)))) (rule (targets reason_string.ml) @@ -95,4 +97,4 @@ reason_recover_parser reason_declarative_lexer reason_lexer reason_oprint reason_parser_explain_raw reason_parser_explain reason_parser_recover reason_string) - (libraries ocaml-migrate-parsetree menhirLib reason.easy_format)) + (libraries ocaml-migrate-parsetree menhirLib reason.easy_format reason.omd)) diff --git a/src/reason-parser/reason_attributes.ml b/src/reason-parser/reason_attributes.ml index db13e7c8b..029ef61fe 100644 --- a/src/reason-parser/reason_attributes.ml +++ b/src/reason-parser/reason_attributes.ml @@ -33,7 +33,7 @@ let rec partitionAttributes ?(partDoc=false) ?(allowUncurry=true) attrs : attrib | ({ attr_name = {txt="ocaml.text"}; _} as doc)::atTl when partDoc = true -> let partition = partitionAttributes ~partDoc ~allowUncurry atTl in {partition with docAttrs=doc::partition.docAttrs} - | ({ attr_name = {txt="ocaml.doc"}; _} as doc)::atTl when partDoc = true -> + | ({ attr_name = {txt="ocaml.doc" | "ocaml.text"}; _} as doc)::atTl when partDoc = true -> let partition = partitionAttributes ~partDoc ~allowUncurry atTl in {partition with docAttrs=doc::partition.docAttrs} | ({ attr_name = {txt="reason.raw_literal"}; _} as attr) :: atTl -> diff --git a/src/reason-parser/reason_parser.mly b/src/reason-parser/reason_parser.mly index 809373e49..a9b1cc74f 100644 --- a/src/reason-parser/reason_parser.mly +++ b/src/reason-parser/reason_parser.mly @@ -140,6 +140,11 @@ module Clflags = Reason_syntax_util.Clflags *) +let make_floating_doc = function + | {attr_name = {txt = "ocaml.doc"; _} as attr_name; _} as attr -> + {attr with attr_name = {attr_name with txt = "ocaml.text"}} + | attr -> attr + let uncurry_payload ?(name="bs") loc = { attr_name = {loc; txt = name}; attr_payload = PStr []; @@ -986,7 +991,7 @@ let mkBsObjTypeSugar ~loc ~closed rows = let doc_loc loc = {txt = "ocaml.doc"; loc = loc} -let doc_attr text loc = +let doc_attr_item text loc = let open Parsetree in let exp = { pexp_desc = Pexp_constant (Pconst_string(text, None)); @@ -995,12 +1000,16 @@ let doc_attr text loc = pexp_loc_stack = []; } in - let item = - { pstr_desc = Pstr_eval (exp, []); pstr_loc = exp.pexp_loc } - in + { pstr_desc = Pstr_eval (exp, []); pstr_loc = exp.pexp_loc } + +let doc_attr text loc = + let open Parsetree in + let markdown_text = (Omd.to_ocamldoc (Omd.of_string text)) in + let ocamldoc_item = doc_attr_item text loc in + let markdown_item = doc_attr_item markdown_text loc in { attr_name = doc_loc loc; - attr_payload = PStr [item]; + attr_payload = PStr [ocamldoc_item; markdown_item]; attr_loc = loc } @@ -1728,8 +1737,12 @@ structure_item: | let_bindings { val_of_let_bindings $1 } ) { [$1] } - | located_attributes - { List.map (fun x -> mkstr ~loc:x.loc (Pstr_attribute x.txt)) $1 } + | located_attributes + { + List.map + (fun x -> mkstr ~loc:x.loc (Pstr_attribute (make_floating_doc x.txt))) + $1 + } ; module_binding_body: @@ -1949,7 +1962,9 @@ signature_item: signature_items: | as_loc(signature_item) { [mksig ~loc:$1.loc $1.txt] } | located_attributes - { List.map (fun x -> mksig ~loc:x.loc (Psig_attribute x.txt)) $1 } + { List.map + (fun x -> mksig ~loc:x.loc (Psig_attribute (make_floating_doc x.txt))) + $1 } ; open_declaration: @@ -2109,7 +2124,9 @@ class_field: { mkcf_attrs (Pcf_extension $2) $1 } ) { [$1] } | located_attributes - { List.map (fun x -> mkcf ~loc:x.loc (Pcf_attribute x.txt)) $1 } + { List.map + (fun x -> mkcf ~loc:x.loc (Pcf_attribute (make_floating_doc x.txt))) + $1 } ; value: @@ -2373,7 +2390,9 @@ class_sig_field: { mkctf_attrs (Pctf_extension $2) $1 } ) { [$1] } | located_attributes - { List.map (fun x -> mkctf ~loc:x.loc (Pctf_attribute x.txt)) $1 } + { List.map + (fun x -> mkctf ~loc:x.loc (Pctf_attribute (make_floating_doc x.txt))) + $1 } ; value_type: @@ -4916,7 +4935,14 @@ attribute: attr_loc = mklocation $symbolstartpos $endpos } } - | DOCSTRING { doc_attr $1 (mklocation $symbolstartpos $endpos) } + | DOCSTRING { + (* Here is where we will make another copy of doc_attr but with + * reason.doc/text instead of ocaml.doc/text and _that_ is the one that the + * printer should pay attention to, completely ignoring the ocaml.doc/text + * ones. The ocaml.doc/text ones would only be received by odoc. *) + (* doc_attr (Omd.to_ocamldoc Omd.of_string ($1)) (mklocation $symbolstartpos $endpos) :: *) + doc_attr $1 (mklocation $symbolstartpos $endpos) + } ; (* Inlined to avoid having to deal with buggy $symbolstartpos *) diff --git a/src/reason-parser/reason_pprint_ast.ml b/src/reason-parser/reason_pprint_ast.ml index f164c1c2d..5f53d0a44 100644 --- a/src/reason-parser/reason_pprint_ast.ml +++ b/src/reason-parser/reason_pprint_ast.ml @@ -6536,6 +6536,15 @@ let printer = object(self:'self) (* [@ ...] Simple attributes *) method attribute = function + (* + In case there are two entries in the AST, use the second one because that + is the markdown text, and ignore the converted ocamldoc text. + *) + | { attr_name = { Location. txt = ("ocaml.doc" | "ocaml.text") } + ; attr_payload = + PStr [_;{ pstr_desc = Pstr_eval ({ pexp_desc = Pexp_constant (Pconst_string(text, None)) } , _); + pstr_loc }] + ; _ } | { attr_name = { Location. txt = ("ocaml.doc" | "ocaml.text") } ; attr_payload = PStr [{ pstr_desc = Pstr_eval ({ pexp_desc = Pexp_constant (Pconst_string(text, None)) } , _); diff --git a/src/reason-parser/vendor/omd/.gitignore b/src/reason-parser/vendor/omd/.gitignore new file mode 100644 index 000000000..f06221ceb --- /dev/null +++ b/src/reason-parser/vendor/omd/.gitignore @@ -0,0 +1,3 @@ +_build/ +.merlin +*.install diff --git a/src/reason-parser/vendor/omd/VERSION b/src/reason-parser/vendor/omd/VERSION new file mode 100644 index 000000000..6f9d89ac0 --- /dev/null +++ b/src/reason-parser/vendor/omd/VERSION @@ -0,0 +1,2 @@ +@jfrolich/omd +f11da5aedf56b25dde528cfe0be54f99e6f58921 diff --git a/src/reason-parser/vendor/omd/src/ast.ml b/src/reason-parser/vendor/omd/src/ast.ml new file mode 100644 index 000000000..60ca90891 --- /dev/null +++ b/src/reason-parser/vendor/omd/src/ast.ml @@ -0,0 +1,119 @@ +type attributes = + (string * string) list + +type 'a link_def = + { + label: 'a; + destination: string; + title: string option; + } + +type list_type = + | Ordered of int * char + | Bullet of char + +type list_spacing = + | Loose + | Tight + +let same_block_list_kind k1 k2 = + match k1, k2 with + | Ordered (_, c1), Ordered (_, c2) + | Bullet c1, Bullet c2 -> c1 = c2 + | _ -> false + +module type T = sig + type t +end + +module MakeBlock (I : T) = struct + type def_elt = + { + term: I.t; + defs: I.t list; + } + + and block = + { + bl_desc: block_desc; + bl_attributes: attributes; + } + + and block_desc = + | Paragraph of I.t + | List of list_type * list_spacing * block list list + | Blockquote of block list + | Thematic_break + | Heading of int * I.t + | Code_block of string * string + | Html_block of string + | Link_def of string link_def + | Definition_list of def_elt list + + let defs ast = + let rec loop acc {bl_desc; bl_attributes} = + match bl_desc with + | List (_, _, bls) -> List.fold_left (List.fold_left loop) acc bls + | Blockquote l -> List.fold_left loop acc l + | Paragraph _ | Thematic_break | Heading _ + | Definition_list _ | Code_block _ | Html_block _ -> acc + | Link_def def -> (def, bl_attributes) :: acc + in + List.rev (List.fold_left loop [] ast) +end + +type inline = + { + il_desc: inline_desc; + il_attributes: attributes; + } + +and inline_desc = + | Concat of inline list + | Text of string + | Emph of inline + | Strong of inline + | Code of string + | Hard_break + | Soft_break + | Link of inline link_def + | Image of inline link_def + | Html of string + +module Raw = MakeBlock (String) + +module Inline = struct type t = inline end + +include MakeBlock (Inline) + +module MakeMapper (Src : T) (Dst : T) = struct + module SrcBlock = MakeBlock(Src) + module DstBlock = MakeBlock(Dst) + + let rec map (f : Src.t -> Dst.t) : SrcBlock.block -> DstBlock.block = + fun {bl_desc; bl_attributes} -> + let bl_desc = + match bl_desc with + | SrcBlock.Paragraph x -> DstBlock.Paragraph (f x) + | List (ty, sp, bl) -> + List (ty, sp, List.map (List.map (map f)) bl) + | Blockquote xs -> + Blockquote (List.map (map f) xs) + | Thematic_break -> + Thematic_break + | Heading (level, text) -> + Heading (level, f text) + | Definition_list l -> + let f {SrcBlock.term; defs} = {DstBlock.term = f term; defs = List.map f defs} in + Definition_list (List.map f l) + | Code_block (label, code) -> + Code_block (label, code) + | Html_block x -> + Html_block x + | Link_def x -> + Link_def x + in + {bl_desc; bl_attributes} +end + +module Mapper = MakeMapper (String) (Inline) diff --git a/src/reason-parser/vendor/omd/src/block.ml b/src/reason-parser/vendor/omd/src/block.ml new file mode 100644 index 000000000..c80467038 --- /dev/null +++ b/src/reason-parser/vendor/omd/src/block.ml @@ -0,0 +1,255 @@ +open Ast + +module Sub = Parser.Sub + +let mk ?(attr = []) desc = + {Ast.Raw.bl_desc = desc; bl_attributes = attr} + +module Pre = struct + type container = + | Rblockquote of t + | Rlist of list_type * list_spacing * bool * int * Raw.block list list * t + | Rparagraph of string list + | Rfenced_code of int * int * Parser.code_block_kind * (string * string) * string list * attributes + | Rindented_code of string list + | Rhtml of Parser.html_kind * string list + | Rdef_list of string * string list + | Rempty + + and t = + { + blocks: Raw.block list; + next: container; + } + + let concat l = String.concat "\n" (List.rev l) ^ "\n" + + let trim_left s = + let rec loop i = + if i >= String.length s then + i + else begin + match s.[i] with + | ' ' | '\t' -> + loop (succ i) + | _ -> + i + end + in + let i = loop 0 in + if i > 0 then String.sub s i (String.length s - i) else s + + let rec close {blocks; next} = + match next with + | Rblockquote state -> + mk (Raw.Blockquote (finish state)) :: blocks + | Rlist (ty, sp, _, _, closed_items, state) -> + mk (List (ty, sp, List.rev (finish state :: closed_items))) :: blocks + | Rparagraph l -> + let s = concat (List.map trim_left l) in + let defs, off = Parser.link_reference_definitions (Parser.P.of_string s) in + let s = String.sub s off (String.length s - off) |> String.trim in + let blocks = + let f (def, attr) blocks = mk ~attr (Raw.Link_def def) :: blocks in + List.fold_right f defs blocks + in + if s = "" then blocks else mk (Paragraph s) :: blocks + | Rfenced_code (_, _, _kind, (label, _other), [], attr) -> + mk ~attr (Code_block (label, "")) :: blocks + | Rfenced_code (_, _, _kind, (label, _other), l, attr) -> + mk ~attr (Code_block (label, concat l)) :: blocks + | Rdef_list (term, defs) -> + let l, blocks = + match blocks with + | {Raw.bl_desc = Definition_list l; _} :: b -> l, b + | b -> [], b + in + mk (Raw.Definition_list (l @ [{ Raw.term; defs = List.rev defs}])) :: blocks + | Rindented_code l -> (* TODO: trim from the right *) + let rec loop = function "" :: l -> loop l | _ as l -> l in + mk (Code_block ("", concat (loop l))) :: blocks + | Rhtml (_, l) -> + mk (Html_block (concat l)) :: blocks + | Rempty -> + blocks + + and finish state = + List.rev (close state) + + let empty = + {blocks = []; next = Rempty} + + let classify_line s = + Parser.parse s + + let rec process {blocks; next} s = + match next, classify_line s with + | Rempty, Parser.Lempty -> + {blocks; next = Rempty} + | Rempty, Lblockquote s -> + {blocks; next = Rblockquote (process empty s)} + | Rempty, Lthematic_break -> + {blocks = mk Thematic_break :: blocks; next = Rempty} + | Rempty, Lsetext_heading (2, n) when n >= 3 -> + {blocks = mk Thematic_break :: blocks; next = Rempty} + | Rempty, Latx_heading (level, text, attr) -> + {blocks = mk ~attr (Heading (level, text)) :: blocks; next = Rempty} + | Rempty, Lfenced_code (ind, num, q, info, a) -> + {blocks; next = Rfenced_code (ind, num, q, info, [], a)} + | Rempty, Lhtml (_, kind) -> + process {blocks; next = Rhtml (kind, [])} s + | Rempty, Lindented_code s -> + {blocks; next = Rindented_code [Sub.to_string s]} + | Rempty, Llist_item (kind, indent, s) -> + {blocks; next = Rlist (kind, Tight, false, indent, [], process empty s)} + | Rempty, (Lsetext_heading _ | Lparagraph | Ldef_list _) -> + {blocks; next = Rparagraph [Sub.to_string s]} + | Rparagraph [h], Ldef_list def -> + {blocks; next = Rdef_list (h, [def])} + | Rdef_list (term, defs), Ldef_list def -> + {blocks; next = Rdef_list (term, def::defs)} + | Rparagraph _, Llist_item ((Ordered (1, _) | Bullet _), _, s1) + when not (Parser.is_empty (Parser.P.of_string (Sub.to_string s1))) -> + process {blocks = close {blocks; next}; next = Rempty} s + | Rparagraph _, (Lempty | Lblockquote _ | Lthematic_break + | Latx_heading _ | Lfenced_code _ | Lhtml (true, _)) -> + process {blocks = close {blocks; next}; next = Rempty} s + | Rparagraph (_ :: _ as lines), Lsetext_heading (level, _) -> + let text = String.trim (String.concat "\n" (List.rev lines)) in + {blocks = mk (Heading (level, text)) :: blocks; next = Rempty} + | Rparagraph lines, _ -> + {blocks; next = Rparagraph (Sub.to_string s :: lines)} + | Rfenced_code (_, num, q, _, _, _), Lfenced_code (_, num', q1, ("", _), _) when num' >= num && q = q1 -> + {blocks = close {blocks; next}; next = Rempty} + | Rfenced_code (ind, num, q, info, lines, a), _ -> + let s = + let ind = min (Parser.indent s) ind in + if ind > 0 then + Sub.offset ind s + else + s + in + {blocks; next = Rfenced_code (ind, num, q, info, Sub.to_string s :: lines, a)} + | Rdef_list (term, d::defs), Lparagraph -> + {blocks; next = Rdef_list (term, (d ^ "\n" ^ (Sub.to_string s))::defs)} + | Rdef_list _, _ -> + process {blocks = close {blocks; next}; next = Rempty} s + | Rindented_code lines, Lindented_code s -> + {blocks; next = Rindented_code (Sub.to_string s :: lines)} + | Rindented_code lines, Lempty -> + let n = min (Parser.indent s) 4 in + let s = Sub.offset n s in + {blocks; next = Rindented_code (Sub.to_string s :: lines)} + | Rindented_code _, _ -> + process {blocks = close {blocks; next}; next = Rempty} s + | Rhtml (Hcontains l as k, lines), _ when List.exists (fun t -> Sub.contains t s) l -> + {blocks = close {blocks; next = Rhtml (k, Sub.to_string s :: lines)}; next = Rempty} + | Rhtml (Hblank, _), Lempty -> + {blocks = close {blocks; next}; next = Rempty} + | Rhtml (k, lines), _ -> + {blocks; next = Rhtml (k, Sub.to_string s :: lines)} + | Rblockquote state, Lblockquote s -> + {blocks; next = Rblockquote (process state s)} + | Rlist (kind, style, _, ind, items, state), Lempty -> + {blocks; next = Rlist (kind, style, true, ind, items, process state s)} + | Rlist (_, _, true, ind, _, {blocks = []; next = Rempty}), _ when Parser.indent s >= ind -> + process {blocks = close {blocks; next}; next = Rempty} s + | Rlist (kind, style, prev_empty, ind, items, state), _ when Parser.indent s >= ind -> + let s = Sub.offset ind s in + let state = process state s in + let style = + let rec new_block = function + | Rblockquote {blocks = []; next} + | Rlist (_, _, _, _, _, {blocks = []; next}) -> new_block next + | Rparagraph [_] + | Rfenced_code (_, _, _, _, [], _) + | Rindented_code [_] + | Rhtml (_, [_]) -> true + | _ -> false + in + if prev_empty && new_block state.next then + Loose + else + style + in + {blocks; next = Rlist (kind, style, false, ind, items, state)} + | Rlist (kind, style, prev_empty, _, items, state), Llist_item (kind', ind, s) + when same_block_list_kind kind kind' -> + let style = if prev_empty then Loose else style in + {blocks; next = Rlist (kind, style, false, ind, finish state :: items, process empty s)} + | (Rlist _ | Rblockquote _), _ -> + let rec loop = function + | Rlist (kind, style, prev_empty, ind, items, {blocks; next}) -> + begin match loop next with + | Some next -> + Some (Rlist (kind, style, prev_empty, ind, items, {blocks; next})) + | None -> + None + end + | Rblockquote {blocks; next} -> + begin match loop next with + | Some next -> + Some (Rblockquote {blocks; next}) + | None -> + None + end + | Rparagraph (_ :: _ as lines) -> + begin match classify_line s with + | Parser.Lparagraph | Lindented_code _ + | Lsetext_heading (1, _) | Lhtml (false, _) -> + Some (Rparagraph (Sub.to_string s :: lines)) + | _ -> + None + end + | _ -> + None + in + begin match loop next with + | Some next -> + {blocks; next} + | None -> + process {blocks = close {blocks; next}; next = Rempty} s + end + + let process state s = + process state (Sub.of_string s) + + let of_channel ic = + let rec loop state = + match input_line ic with + | s -> + loop (process state s) + | exception End_of_file -> + finish state + in + loop empty + + let read_line s off = + let buf = Buffer.create 128 in + let rec loop cr_read off = + if off >= String.length s then + Buffer.contents buf, None + else begin + match s.[off] with + | '\n' -> + Buffer.contents buf, Some (succ off) + | '\r' -> + if cr_read then Buffer.add_char buf '\r'; + loop true (succ off) + | c -> + if cr_read then Buffer.add_char buf '\r'; + Buffer.add_char buf c; + loop false (succ off) + end + in + loop false off + + let of_string s = + let rec loop state = function + | None -> finish state + | Some off -> + let s, off = read_line s off in + loop (process state s) off + in + loop empty (Some 0) +end diff --git a/src/reason-parser/vendor/omd/src/block.mli b/src/reason-parser/vendor/omd/src/block.mli new file mode 100644 index 000000000..46d56fa09 --- /dev/null +++ b/src/reason-parser/vendor/omd/src/block.mli @@ -0,0 +1,10 @@ +module Pre : sig + type t + + val empty: t + val process: t -> string -> t + val finish: t -> Ast.Raw.block list + + val of_channel: in_channel -> Ast.Raw.block list + val of_string: string -> Ast.Raw.block list +end diff --git a/src/reason-parser/vendor/omd/src/compat.ml b/src/reason-parser/vendor/omd/src/compat.ml new file mode 100644 index 000000000..e5bca0742 --- /dev/null +++ b/src/reason-parser/vendor/omd/src/compat.ml @@ -0,0 +1,32 @@ +module Uchar = struct + include Uchar + let rep: Uchar.t = Obj.magic(0xFFFD) +end + +module List = struct + include List + let rec find_opt p = function + | [] -> None + | x :: l -> if p x then Some x else find_opt p l +end + +module Buffer = struct + include Buffer + let add_utf_8_uchar b u = match Uchar.to_int u with + | u when u < 0 -> assert false + | u when u <= 0x007F -> + Buffer.add_char b (Char.unsafe_chr u) + | u when u <= 0x07FF -> + Buffer.add_char b (Char.unsafe_chr (0xC0 lor (u lsr 6))); + Buffer.add_char b (Char.unsafe_chr (0x80 lor (u land 0x3F))) + | u when u <= 0xFFFF -> + Buffer.add_char b (Char.unsafe_chr (0xE0 lor (u lsr 12))); + Buffer.add_char b (Char.unsafe_chr (0x80 lor ((u lsr 6) land 0x3F))); + Buffer.add_char b (Char.unsafe_chr (0x80 lor (u land 0x3F))) + | u when u <= 0x10FFFF -> + Buffer.add_char b (Char.unsafe_chr (0xF0 lor (u lsr 18))); + Buffer.add_char b (Char.unsafe_chr (0x80 lor ((u lsr 12) land 0x3F))); + Buffer.add_char b (Char.unsafe_chr (0x80 lor ((u lsr 6) land 0x3F))); + Buffer.add_char b (Char.unsafe_chr (0x80 lor (u land 0x3F))) + | _ -> assert false +end diff --git a/src/reason-parser/vendor/omd/src/dune b/src/reason-parser/vendor/omd/src/dune new file mode 100644 index 000000000..45ca5afa5 --- /dev/null +++ b/src/reason-parser/vendor/omd/src/dune @@ -0,0 +1,12 @@ +(library + (name omd) + (libraries str) + (public_name reason.omd) + (flags :standard -w -30)) + +(rule + (with-stdout-to + entities.ml + (chdir + ../tools + (run ./gen_entities.exe %{dep:../tools/entities.json})))) diff --git a/src/reason-parser/vendor/omd/src/html.ml b/src/reason-parser/vendor/omd/src/html.ml new file mode 100644 index 000000000..df8b208f7 --- /dev/null +++ b/src/reason-parser/vendor/omd/src/html.ml @@ -0,0 +1,212 @@ +open Ast + +type element_type = + | Inline + | Block + +type t = + | Element of element_type * string * attributes * t option + | Text of string + | Raw of string + | Null + | Concat of t * t + +let elt etype name attrs childs = + Element (etype, name, attrs, childs) + +let text s = Text s + +let raw s = Raw s + +let concat t1 t2 = + match t1, t2 with + | Null, t | t, Null -> t + | _ -> Concat (t1, t2) + +let concat_map f l = + List.fold_left (fun accu x -> concat accu (f x)) Null l + +(* only convert when "necessary" *) +let htmlentities s = + let b = Buffer.create (String.length s) in + let rec loop i = + if i >= String.length s then + Buffer.contents b + else begin + begin match s.[i] with + | '"' -> + Buffer.add_string b """ + | '&' -> + Buffer.add_string b "&" + | '<' -> + Buffer.add_string b "<" + | '>' -> + Buffer.add_string b ">" + | c -> + Buffer.add_char b c + end; + loop (succ i) + end + in + loop 0 + +let add_attrs_to_buffer buf attrs = + let f (k, v) = Printf.bprintf buf " %s=\"%s\"" k (htmlentities v) in + List.iter f attrs + +let rec add_to_buffer buf = function + | Element (eltype, name, attrs, None) -> + Printf.bprintf buf "<%s%a />" + name add_attrs_to_buffer attrs; + if eltype = Block then Buffer.add_char buf '\n' + | Element (eltype, name, attrs, Some c) -> + Printf.bprintf buf "<%s%a>%a" + name add_attrs_to_buffer attrs add_to_buffer c name; + if eltype = Block then Buffer.add_char buf '\n' + | Text s -> + Buffer.add_string buf (htmlentities s) + | Raw s -> + Buffer.add_string buf s + | Null -> + () + | Concat (t1, t2) -> + add_to_buffer buf t1; + add_to_buffer buf t2 + +let escape_uri s = + let b = Buffer.create (String.length s) in + String.iter (function + | '!' | '*' | '\'' | '(' | ')' | ';' | ':' + | '@' | '=' | '+' | '$' | ',' | '/' | '?' | '%' + | '#' | 'A'..'Z' | 'a'..'z' | '0'..'9' | '-' | '_' | '.' | '~' as c -> + Buffer.add_char b c + | '&' -> + Buffer.add_string b "&" + | _ as c -> + Printf.bprintf b "%%%2X" (Char.code c) + ) s; + Buffer.contents b + +let to_plain_text t = + let buf = Buffer.create 1024 in + let rec go = function + | Element (_, _, _, Some t) -> go t + | Text t -> Buffer.add_string buf t + | Concat (t1, t2) -> go t1; go t2 + | _ -> () + in + go t; + Buffer.contents buf + +let nl = Raw "\n" + +let rec url label destination title attrs = + let attrs = + match title with + | None -> attrs + | Some title -> ("title", title) :: attrs + in + let attrs = ("href", escape_uri destination) :: attrs in + elt Inline "a" attrs (Some (inline label)) + +and img label destination title attrs = + let attrs = + match title with + | None -> attrs + | Some title -> ("title", title) :: attrs + in + let attrs = + ("src", escape_uri destination) :: + ("alt", to_plain_text (inline label)) :: attrs + in + elt Inline "img" attrs None + +and inline {il_desc; il_attributes = attr} = + match il_desc with + | Concat l -> + concat_map inline l + | Text t -> + text t + | Emph il -> + elt Inline "em" attr (Some (inline il)) + | Strong il -> + elt Inline "strong" attr (Some (inline il)) + | Code s -> + elt Inline "code" attr (Some (text s)) + | Hard_break -> + concat (elt Inline "br" attr None) nl + | Soft_break -> + nl + | Html body -> + raw body + | Link {label; destination; title} -> + url label destination title attr + | Image {label; destination; title} -> + img label destination title attr + +let rec block {bl_desc; bl_attributes = attr} = + match bl_desc with + | Blockquote q -> + elt Block "blockquote" attr + (Some (concat nl (concat_map block q))) + | Paragraph md -> + elt Block "p" attr (Some (inline md)) + | List (ty, sp, bl) -> + let name = match ty with Ordered _ -> "ol" | Bullet _ -> "ul" in + let attr = + match ty with + | Ordered (n, _) when n <> 1 -> + ("start", string_of_int n) :: attr + | _ -> + attr + in + let li t = + let block' t = + match t.bl_desc, sp with + | Paragraph t, Tight -> concat (inline t) nl + | _ -> block t + in + let nl = if sp = Tight then Null else nl in + elt Block "li" [] (Some (concat nl (concat_map block' t))) in + elt Block name attr (Some (concat nl (concat_map li bl))) + | Code_block (label, code) -> + let code_attr = + if String.trim label = "" then [] + else ["class", "language-" ^ label] + in + let c = text code in + elt Block "pre" attr + (Some (elt Inline "code" code_attr (Some c))) + | Thematic_break -> + elt Block "hr" attr None + | Html_block body -> + raw body + | Heading (level, text) -> + let name = + match level with + | 1 -> "h1" + | 2 -> "h2" + | 3 -> "h3" + | 4 -> "h4" + | 5 -> "h5" + | 6 -> "h6" + | _ -> "p" + in + elt Block name attr (Some (inline text)) + | Definition_list l -> + let f {term; defs} = + concat + (elt Block "dt" [] (Some (inline term))) + (concat_map (fun s -> elt Block "dd" [] (Some (inline s))) defs) + in + elt Block "dl" attr (Some (concat_map f l)) + | Link_def _ -> + Null + +let of_doc doc = + concat_map block doc + +let to_string t = + let buf = Buffer.create 1024 in + add_to_buffer buf t; + Buffer.contents buf diff --git a/src/reason-parser/vendor/omd/src/html.mli b/src/reason-parser/vendor/omd/src/html.mli new file mode 100644 index 000000000..de086f74a --- /dev/null +++ b/src/reason-parser/vendor/omd/src/html.mli @@ -0,0 +1,18 @@ +open Ast + +type element_type = + | Inline + | Block + +type t = + | Element of element_type * string * attributes * t option + | Text of string + | Raw of string + | Null + | Concat of t * t + +val of_doc : block list -> t + +val to_string : t -> string + +val to_plain_text : t -> string diff --git a/src/reason-parser/vendor/omd/src/ocamldoc.ml b/src/reason-parser/vendor/omd/src/ocamldoc.ml new file mode 100644 index 000000000..5af985fbd --- /dev/null +++ b/src/reason-parser/vendor/omd/src/ocamldoc.ml @@ -0,0 +1,151 @@ +open Ast + +type t = + | TripleSurround of string * t * string * t * string + | Surround of string * t * string + | BlockSurround of string * t * string + | GeneralBlock of t + | Text of string + | Raw of string + | Null + | Concat of t * t + +let nl = Raw "\n" + +let escape_uri s = + let b = Buffer.create (String.length s) in + String.iter (function + | '!' | '*' | '\'' | '(' | ')' | ';' | ':' + | '@' | '=' | '+' | '$' | ',' | '/' | '?' | '%' + | '#' | 'A'..'Z' | 'a'..'z' | '0'..'9' | '-' | '_' | '.' | '~' as c -> + Buffer.add_char b c + | '&' -> + Buffer.add_string b "&" + | _ as c -> + Printf.bprintf b "%%%2X" (Char.code c) + ) s; + Buffer.contents b + +let to_plain_text t = + let buf = Buffer.create 1024 in + let rec go = function + | Text t -> Buffer.add_string buf t + | Concat (t1, t2) -> go t1; go t2 + | _ -> () + in + go t; + Buffer.contents buf + +let rec add_to_buffer buf = function + | TripleSurround (s1, t1, s2, t2, s3) -> + Printf.bprintf buf "%s%a%s%a%s" s1 add_to_buffer t1 s2 add_to_buffer t2 s3 + | Surround (s1, t1, s2) -> Printf.bprintf buf "%s%a%s" s1 add_to_buffer t1 s2 + | BlockSurround (s1, t1, s2) -> Printf.bprintf buf "\n\b%s%a%s\n" s1 add_to_buffer t1 s2 + | GeneralBlock (t) -> Printf.bprintf buf "\n%a\n" add_to_buffer t + | Text s -> Buffer.add_string buf s + | Raw s -> Buffer.add_string buf s + | Null -> () + | Concat (t1, t2) -> + add_to_buffer buf t1; + add_to_buffer buf t2 + +let text s = Text s +let raw s = Raw s +let concat s1 s2 = match (s1, s2) with + | Null, s + | s, Null -> s + | s1, s2 -> Concat(s1, s2) + +let concat_map f l = + List.fold_left (fun accu x -> concat accu (f x)) Null l + +let cross_reference_words = [ + "module"; + "modtype"; + "class"; + "classtype"; + "val"; + "type"; + "exception"; + "attribute"; + "method"; + "section"; + "const"; + "recfield"; +] + +let is_cross_reference_regexps = cross_reference_words |> List.map(fun w -> (Str.regexp_string (w ^ ":"))) +let inferred_cross_reference = Str.regexp_string("ref:") + +let rec inline {il_desc; il_attributes = _} = + match il_desc with + | Concat l -> concat_map inline l + | Text s -> text s + | Emph il -> Surround ("{e ", inline il, "}") + | Strong il -> Surround ("{b ", inline il, "}") + | Code s -> Surround ("[", text s, "]") + | Hard_break -> text "\n\n" + | Soft_break -> text "\n" + | Html body -> Surround ("{%html: ", (text body), "%}") + | Link {label; destination; title = _} -> + let cross_reference = match label with + | {il_desc = Text s; _} when s == destination -> + if (Str.string_match inferred_cross_reference destination 0) then + Some(Str.string_after destination 4) + else + if List.exists (fun r -> Str.string_match r destination 0) is_cross_reference_regexps then Some(destination) else None + | _ -> + None in + ( + match cross_reference with + | Some(cross_reference) -> + Surround("{!", (text cross_reference), "}") + | None -> + TripleSurround("{{: ", (text destination), "} ", inline label, "}") + ) + | Image {label; destination; title} -> + let img = "\"" "" + | Some title -> " title=\"" ^ title ^ "\"") ^ "/>" in + Surround ("{%html: ", text img, "%}") + + +let rec block {bl_desc; bl_attributes = _attr} = + match bl_desc with + | Blockquote q -> BlockSurround("{v ", (concat_map block q), "v}") + | Paragraph md -> GeneralBlock(inline md) + | List (ty, sp, bl) -> + let sign = match ty with Ordered _ -> "+ " | Bullet _ -> "- " in + let li t = + let block' t = + match t.bl_desc, sp with + | Paragraph t, Tight -> concat (inline t) nl + | _ -> block t + in + let nl = if sp = Tight then Null else nl in + Surround (sign, concat nl (concat_map block' t), "") in + concat nl (concat_map li bl) + | Code_block (_label, code) -> + BlockSurround("{[\n", text code, "]}") + | Thematic_break -> GeneralBlock(text "***") + | Html_block body -> raw body + | Heading(level, text) -> + BlockSurround("{" ^ ( + match level with + | 1 -> "0" + | 2 -> "1" + | 3 -> "2" + | 4 -> "3" + | 5 -> "4" + | _ -> "5" + ) ^ " ", inline text, "}") + | Definition_list _ -> Null + | Link_def _ -> Null + +let of_doc doc = + concat_map block doc + +let to_string t = + let buf = Buffer.create 1024 in + add_to_buffer buf t; + Buffer.contents buf; diff --git a/src/reason-parser/vendor/omd/src/ocamldoc.mli b/src/reason-parser/vendor/omd/src/ocamldoc.mli new file mode 100644 index 000000000..4fb8ef6ed --- /dev/null +++ b/src/reason-parser/vendor/omd/src/ocamldoc.mli @@ -0,0 +1,15 @@ +open Ast + +type t = + | TripleSurround of string * t * string * t * string + | Surround of string * t * string + | BlockSurround of string * t * string + | GeneralBlock of t + | Text of string + | Raw of string + | Null + | Concat of t * t + +val of_doc: block list -> t + +val to_string : t -> string diff --git a/src/reason-parser/vendor/omd/src/omd.ml b/src/reason-parser/vendor/omd/src/omd.ml new file mode 100644 index 000000000..ff833ee01 --- /dev/null +++ b/src/reason-parser/vendor/omd/src/omd.ml @@ -0,0 +1,32 @@ +module Pre = Block.Pre + +include Ast + +type doc = block list + +let parse_inline defs s = + Parser.inline defs (Parser.P.of_string s) + +let parse_inlines md = + let defs = + let f (def, attr) = {def with label = Parser.normalize def.label}, attr in + List.map f (Raw.defs md) + in + List.map (Mapper.map (parse_inline defs)) md + +let of_channel ic = + let md = Pre.of_channel ic in + parse_inlines md + +let of_string s = + let md = Pre.of_string s in + parse_inlines md + +let to_html doc = + Html.to_string (Html.of_doc doc) + +let to_sexp ast = + Format.asprintf "@[%a@]@." Sexp.print (Sexp.create ast) + +let to_ocamldoc doc = + Ocamldoc.to_string (Ocamldoc.of_doc doc) diff --git a/src/reason-parser/vendor/omd/src/omd.mli b/src/reason-parser/vendor/omd/src/omd.mli new file mode 100644 index 000000000..d9a7f71d9 --- /dev/null +++ b/src/reason-parser/vendor/omd/src/omd.mli @@ -0,0 +1,73 @@ +(** A markdown parser in OCaml. *) + +type attributes = + (string * string) list + +type 'a link_def = + { + label: 'a; + destination: string; + title: string option; + } + +type inline = + { + il_desc: inline_desc; + il_attributes: attributes; + } + +and inline_desc = + | Concat of inline list + | Text of string + | Emph of inline + | Strong of inline + | Code of string + | Hard_break + | Soft_break + | Link of inline link_def + | Image of inline link_def + | Html of string + +type list_type = + | Ordered of int * char + | Bullet of char + +type list_spacing = + | Loose + | Tight + +type def_elt = + { + term: inline; + defs: inline list; + } + +and block = + { + bl_desc: block_desc; + bl_attributes: attributes; + } + +and block_desc = + | Paragraph of inline + | List of list_type * list_spacing * block list list + | Blockquote of block list + | Thematic_break + | Heading of int * inline + | Code_block of string * string + | Html_block of string + | Link_def of string link_def + | Definition_list of def_elt list + +type doc = block list +(** A markdown document *) + +val of_channel: in_channel -> doc + +val of_string: string -> doc + +val to_html: doc -> string + +val to_sexp: doc -> string + +val to_ocamldoc: doc -> string diff --git a/src/reason-parser/vendor/omd/src/parser.ml b/src/reason-parser/vendor/omd/src/parser.ml new file mode 100644 index 000000000..ac949c158 --- /dev/null +++ b/src/reason-parser/vendor/omd/src/parser.ml @@ -0,0 +1,1889 @@ +open Ast +open Compat + +module Sub : sig + type t + + val of_string: string -> t + val to_string: t -> string + val offset: int -> t -> t + val lexbuf: t -> Lexing.lexbuf + val contains: string -> t -> bool + + val print: Format.formatter -> t -> unit + + val head: ?rev:unit -> t -> char option + val tail: ?rev:unit -> t -> t + + val heads: int -> t -> char list + val tails: int -> t -> t + + val for_all: (char -> bool) -> t -> bool + val exists: (char -> bool) -> t -> bool + val is_empty: t -> bool + val length: t -> int + + val sub: len:int -> t -> t +end = struct + type t = + { + base: string; + off: int; + len: int; + } + + let of_string base = + {base; off = 0; len = String.length base} + + let to_string {base; off; len} = + String.sub base off len + + let print ppf s = + Format.fprintf ppf "%S" (to_string s) + + let length {len; _} = + len + + let offset n {base; off; len} = + if n < 0 then invalid_arg "offset"; + let rec loop n base off len = + if n = 0 || len = 0 then + {base; off; len} + else begin + match base.[off] with + | '\t' -> + let ts = (off + 4) / 4 * 4 - off in + let b = Buffer.create len in + Buffer.add_substring b base 0 off; + for _ = 1 to ts do Buffer.add_char b ' ' done; + Buffer.add_substring b base (off + 1) (len - 1); + loop n (Buffer.contents b) off (len + ts - 1) + | _ -> + loop (n - 1) base (off + 1) (len - 1) + end + in + loop n base off len + + let lexbuf s = + Lexing.from_string (to_string s) + + let contains s1 {base; off; len} = + let rec loop off = + if off + String.length s1 > len then + false + else + s1 = String.sub base off (String.length s1) || loop (off + 1) + in + loop off + + let head ?rev s = + match rev, s with + | _, {len = 0; _} -> + None + | None, {base; off; _} -> + Some base.[off] + | Some (), {base; off; len} -> + Some base.[off + len - 1] + + let tail ?rev s = + match rev, s with + | _, {len = 0; _} -> + s + | None, {base; off; len} -> + {base; off = succ off; len = pred len} + | Some (), {base; off; len} -> + {base; off; len = pred len} + + let heads n s = + if n < 0 then invalid_arg "heads"; + let rec loop n s = + if n = 0 || length s = 0 then [] + else match head s with + | Some c -> c :: loop (pred n) (tail s) + | None -> [] + in + loop n s + + let tails n s = + if n < 0 then invalid_arg "tails"; + let rec loop n s = + if n = 0 then s + else loop (pred n) (tail s) + in + loop n s + + let is_empty s = + length s = 0 + + let exists f s = + let rec loop s i = + if i >= s.len then + false + else if f s.base.[s.off + i] then + true + else + loop s (succ i) + in + loop s 0 + + let for_all f s = + not (exists (fun c -> not (f c)) s) + + let sub ~len s = + if len > s.len then invalid_arg "sub"; + {s with len} +end + +exception Fail + +module P : sig + type state + type 'a t = state -> 'a + + val of_string: string -> state + val peek: char option t + val peek_exn: char t + val pos: state -> int + val range: state -> int -> int -> string + val set_pos: state -> int -> unit + val junk: unit t + val char: char -> unit t + val next: char t + val (|||): 'a t -> 'a t -> 'a t + val ws: unit t + val sp: unit t + val ws1: unit t + val (>>>): unit t -> 'a t -> 'a t + val (<<<): 'a t -> unit t -> 'a t + val protect: 'a t -> 'a t + val peek_before: char -> state -> char + val peek_after: char -> state -> char + val pair: 'a t -> 'b t -> ('a * 'b) t +end = struct + type state = + { + str: string; + mutable pos: int; + } + + let of_string str = + {str; pos = 0} + + type 'a t = + state -> 'a + + let char c st = + if st.pos >= String.length st.str then raise Fail; + if st.str.[st.pos] <> c then raise Fail; + st.pos <- st.pos + 1 + + let next st = + if st.pos >= String.length st.str then + raise Fail + else + let c = st.str.[st.pos] in (st.pos <- st.pos + 1; c) + + let peek_exn st = + if st.pos >= String.length st.str then + raise Fail + else + st.str.[st.pos] + + let peek st = + if st.pos >= String.length st.str then + None + else + Some st.str.[st.pos] + + let peek_before c st = + if st.pos = 0 then c + else st.str.[st.pos - 1] + + let peek_after c st = + if st.pos + 1 >= String.length st.str then c + else st.str.[st.pos + 1] + + let pos st = + st.pos + + let range st pos n = + String.sub st.str pos n + + let set_pos st pos = + st.pos <- pos + + let junk st = + if st.pos < String.length st.str then st.pos <- st.pos + 1 + + let protect p st = + let off = pos st in + try p st with e -> set_pos st off; raise e + + let (|||) p1 p2 st = + try protect p1 st with Fail -> p2 st + + let ws st = + let rec loop () = + match peek_exn st with + | ' ' | '\t' | '\010'..'\013' -> junk st; loop () + | _ -> () + in + try loop () with Fail -> () + + let sp st = + let rec loop () = + match peek_exn st with + | ' ' | '\t' -> junk st; loop () + | _ -> () + in + try loop () with Fail -> () + + let ws1 st = + match peek_exn st with + | ' ' | '\t' | '\010'..'\013' -> junk st; ws st + | _ -> raise Fail + + let (>>>) p q st = + p st; q st + + let (<<<) p q st = + let x = p st in + q st; x + + let pair p q st = + let x = p st in + let y = q st in + x, y +end + +type html_kind = + | Hcontains of string list + | Hblank + +type code_block_kind = + | Tilde + | Backtick + +type t = + | Lempty + | Lblockquote of Sub.t + | Lthematic_break + | Latx_heading of int * string * attributes + | Lsetext_heading of int * int + | Lfenced_code of int * int * code_block_kind * (string * string) * attributes + | Lindented_code of Sub.t + | Lhtml of bool * html_kind + | Llist_item of list_type * int * Sub.t + | Lparagraph + | Ldef_list of string + +let sp3 s = + match Sub.head s with + | Some ' ' -> + let s = Sub.tail s in + begin match Sub.head s with + | Some ' ' -> + let s = Sub.tail s in + begin match Sub.head s with + | Some ' ' -> 3, Sub.tail s + | Some _ | None -> 2, s + end + | Some _ | None -> 1, s + end + | Some _ | None -> 0, s + +let (|||) p1 p2 s = + try p1 s with Fail -> p2 s + +let rec ws ?rev s = + match Sub.head ?rev s with + | Some (' ' | '\t' | '\010'..'\013') -> ws ?rev (Sub.tail ?rev s) + | None | Some _ -> s + +let is_empty s = + Sub.is_empty (ws s) + +let thematic_break s = + match Sub.head s with + | Some ('*' | '_' | '-' as c) -> + let rec loop n s = + match Sub.head s with + | Some c1 when c = c1 -> + loop (succ n) (Sub.tail s) + | Some (' ' | '\t' | '\010'..'\013') -> + loop n (Sub.tail s) + | Some _ -> + raise Fail + | None -> + if n < 3 then raise Fail; + Lthematic_break + in + loop 1 (Sub.tail s) + | Some _ | None -> + raise Fail + +let setext_heading s = + match Sub.head s with + | Some ('-' | '=' as c) -> + let rec loop n s = + match Sub.head s with + | Some c1 when c = c1 -> + loop (succ n) (Sub.tail s) + | Some _ | None -> + if not (Sub.is_empty (ws s)) then raise Fail; + if c = '-' && n = 1 then raise Fail; (* can be interpreted as an empty list item *) + Lsetext_heading ((if c = '-' then 2 else 1), n) + in + loop 1 (Sub.tail s) + | Some _ | None -> + raise Fail + +let is_punct = function + | '!' | '"' | '#' | '$' | '%' | '&' | '\'' | '(' | ')' + | '*' | '+' | ',' | '-' | '.' | '/' | ':' | ';' | '<' + | '=' | '>' | '?' | '@' | '[' | '\\' | ']' | '^' | '_' + | '`' | '{' | '|' | '}' | '~' -> true + | _ -> false + +let parse_attributes = function + | None -> [] + | Some s -> + let attributes = String.split_on_char ' ' s in + let f (id, classes, acc) s = + if s = "" then (id, classes, acc) + else begin + match s.[0] with + | '#' -> + (Some (String.sub s 1 (String.length s - 1)), classes, acc) + | '.' -> + (id, String.sub s 1 (String.length s - 1) :: classes, acc) + | _ -> + let attr = String.split_on_char '=' s in + match attr with + | [] -> (id, classes, acc) + | h::t -> (id, classes, (h, String.concat "=" t) :: acc) + end + in + let id, classes, acc = List.fold_left f (None, [], []) attributes in + let acc = List.rev acc in + let acc = + if classes <> [] then ("class", String.concat " " (List.rev classes)) :: acc + else acc in + match id with + | Some id -> ("id", id) :: acc + | None -> acc + +let attribute_string s = + let buf = Buffer.create 64 in + let rec loop s = + match Sub.head s with + | None -> + Sub.of_string (Buffer.contents buf), None + | Some ('\\' as c) -> + let s = Sub.tail s in + begin match Sub.head s with + | Some c when is_punct c -> + Buffer.add_char buf c; + loop (Sub.tail s) + | Some _ | None -> + Buffer.add_char buf c; + loop s + end + | Some '{' -> + let buf' = Buffer.create 64 in + let rec loop' s = + match Sub.head s with + | Some '}' -> + let s = Sub.tail s in + begin match Sub.head s with + | Some _ -> + Buffer.add_char buf '{'; + Buffer.add_buffer buf buf'; + Buffer.add_char buf '}'; + loop s + | None -> + Sub.of_string (Buffer.contents buf), Some (Buffer.contents buf') + end + | None -> + Buffer.add_char buf '{'; + Buffer.add_buffer buf buf'; + Sub.of_string (Buffer.contents buf), None + | Some '{' -> + Buffer.add_char buf '{'; + Buffer.add_buffer buf buf'; + Buffer.reset buf'; + loop' (Sub.tail s) + | Some c -> + Buffer.add_char buf' c; + loop' (Sub.tail s) + in + loop' (Sub.tail s) + | Some c -> + Buffer.add_char buf c; + loop (Sub.tail s) + in + let s', a = loop (ws s) in + s', parse_attributes a + +let atx_heading s = + let rec loop n s = + if n > 6 then raise Fail; + match Sub.head s with + | Some '#' -> + loop (succ n) (Sub.tail s) + | Some (' ' | '\t' | '\010'..'\013') -> + let s, a = + match Sub.head ~rev:() s with + | Some '}' -> + attribute_string s + | _ -> + s, [] + in + let s = ws ~rev:() (ws s) in + let rec loop t = + match Sub.head ~rev:() t with + | Some '#' -> + loop (Sub.tail ~rev:() t) + | Some (' ' | '\t' | '\010'..'\013') | None -> + ws ~rev:() t + | Some _ -> + s + in + Latx_heading (n, Sub.to_string (ws (loop s)), a) + | Some _ -> + raise Fail + | None -> + Latx_heading (n, Sub.to_string s, []) + in + loop 0 s + +let entity s = + match Sub.heads 2 s with + | '#' :: ('x' | 'X') :: _ -> + let rec loop m n s = + if m > 8 then raise Fail; + match Sub.head s with + | Some ('a'..'f' as c) -> + loop (succ m) (n * 16 + Char.code c - Char.code 'a' + 10) (Sub.tail s) + | Some ('A'..'F' as c) -> + loop (succ m) (n * 16 + Char.code c - Char.code 'A' + 10) (Sub.tail s) + | Some ('0'..'9' as c) -> + loop (succ m) (n * 16 + Char.code c - Char.code '0') (Sub.tail s) + | Some ';' -> + if m = 0 then raise Fail; + let u = if n = 0 || not (Uchar.is_valid n) then Uchar.rep else Uchar.of_int n in + [u], Sub.tail s + | Some _ | None -> + raise Fail + in + loop 0 0 (Sub.tails 2 s) + | '#' :: _ -> + let rec loop m n s = + if m > 8 then raise Fail; + match Sub.head s with + | Some ('0'..'9' as c) -> + loop (succ m) (n * 10 + Char.code c - Char.code '0') (Sub.tail s) + | Some ';' -> + if m = 0 then raise Fail; + let u = if n = 0 || not (Uchar.is_valid n) then Uchar.rep else Uchar.of_int n in + [u], Sub.tail s + | Some _ | None -> + raise Fail + in + loop 0 0 (Sub.tail s) + | ('a'..'z' | 'A'..'Z') :: _ -> + let rec loop len t = + match Sub.head t with + | Some ('a'..'z' | 'A'..'Z' | '0'..'9') -> + loop (succ len) (Sub.tail t) + | Some ';' -> + let name = Sub.to_string (Sub.sub ~len s) in + begin match Entities.f name with + | [] -> raise Fail + | cps -> cps, Sub.tail t + end + | Some _ | None -> + raise Fail + in + loop 1 (Sub.tail s) + | _ -> + raise Fail + +let info_string c s = + let buf = Buffer.create 17 in + let s, a = + match Sub.head ~rev:() s with + | Some '}' -> + attribute_string s + | _ -> + s, [] + in + let s = ws ~rev:() (ws s) in + let rec loop s = + match Sub.head s with + | Some (' ' | '\t' | '\010'..'\013') | None -> + if c = '`' && Sub.exists (function '`' -> true | _ -> false) s then raise Fail; + (Buffer.contents buf, Sub.to_string (ws s)), a + | Some '`' when c = '`' -> + raise Fail + | Some ('\\' as c) -> + let s = Sub.tail s in + begin match Sub.head s with + | Some c when is_punct c -> + Buffer.add_char buf c; + loop (Sub.tail s) + | Some _ | None -> + Buffer.add_char buf c; + loop s + end + | Some ('&' as c) -> + let s = Sub.tail s in + begin match entity s with + | (ul, s) -> + List.iter (Buffer.add_utf_8_uchar buf) ul; + loop s + | exception Fail -> + Buffer.add_char buf c; + loop s + end + | Some c -> + Buffer.add_char buf c; + loop (Sub.tail s) + in + loop (ws s) + +let fenced_code ind s = + match Sub.head s with + | Some ('`' | '~' as c) -> + let rec loop n s = + match Sub.head s with + | Some c1 when c = c1 -> + loop (succ n) (Sub.tail s) + | Some _ | None -> + if n < 3 then raise Fail; + let s, a = info_string c s in + let c = if c = '`' then Backtick else Tilde in + Lfenced_code (ind, n, c, s, a) + in + loop 1 (Sub.tail s) + | Some _ | None -> + raise Fail + +let indent s = + let rec loop n s = + match Sub.head s with + | Some ' ' -> + loop (n + 1) (Sub.tail s) + | Some '\t' -> + loop (n + 4) (Sub.tail s) + | Some _ | None -> + n + in + loop 0 s + +let unordered_list_item ind s = + match Sub.head s with + | Some ('+' | '-' | '*' as c) -> + let s = Sub.tail s in + if is_empty s then + Llist_item (Bullet c, 2 + ind, s) + else + let n = indent s in + if n = 0 then raise Fail; + let n = if n <= 4 then n else 1 in + Llist_item (Bullet c, n + 1 + ind, Sub.offset n s) + | Some _ | None -> + raise Fail + +let ordered_list_item ind s = + let rec loop n m s = + match Sub.head s with + | Some ('0'..'9' as c) -> + if n >= 9 then raise Fail; + loop (succ n) (m * 10 + Char.code c - Char.code '0') (Sub.tail s) + | Some ('.' | ')' as c) -> + let s = Sub.tail s in + if is_empty s then + Llist_item (Ordered (m, c), n + 1 + ind, s) + else begin + let ind' = indent s in + if ind' = 0 then raise Fail; + let ind' = if ind' <= 4 then ind' else 1 in + Llist_item (Ordered (m, c), n + ind + ind' + 1, Sub.offset ind' s) + end + | Some _ | None -> + raise Fail + in + loop 0 0 s + +let tag_name s0 = + match Sub.head s0 with + | Some ('a'..'z' | 'A'..'Z') -> + let rec loop len s = + match Sub.head s with + | Some ('a'..'z' | 'A'..'Z' | '0'..'9' | '-') -> + loop (succ len) (Sub.tail s) + | Some _ | None -> + Sub.to_string (Sub.sub s0 ~len), s + in + loop 1 (Sub.tail s0) + | Some _ | None -> + raise Fail + +let known_tags = + [ "address"; "aside"; "base"; "basefont"; "blockquote"; + "body"; "caption"; "center"; "col"; "colgroup"; "dd"; + "details"; "dialog"; "dir"; "div"; "dl"; "dt"; + "fieldset"; "figcaption"; "figure"; "footer"; "form"; + "frame"; "frameset"; "h1"; "h2"; "h3"; "h4"; "h5"; + "h6"; "head"; "header"; "hr"; "html"; "iframe"; "legend"; + "li"; "link"; "main"; "menu"; "menuitem"; "meta"; "nav"; + "noframes"; "ol"; "optgroup"; "option"; "p"; "param"; + "section"; "source"; "summary"; "table"; "tbody"; + "td"; "tfoot"; "th"; "thead"; "title"; "tr"; "track"; "ul" ] + +let special_tags = + [ "script"; "pre"; "style" ] + +let known_tag s = + let s = String.lowercase_ascii s in + List.mem s known_tags + +let special_tag s = + let s = String.lowercase_ascii s in + List.mem s special_tags + +let closing_tag s = + let s = ws s in + match Sub.head s with + | Some '>' -> + if not (is_empty (Sub.tail s)) then raise Fail; + Lhtml (false, Hblank) + | Some _ | None -> + raise Fail + +let special_tag tag s = + if not (special_tag tag) then raise Fail; + match Sub.head s with + | Some (' ' | '\t' | '\010'..'\013' | '>') | None -> + Lhtml (true, Hcontains [""; ""; ""]) + | Some _ -> + raise Fail + +let known_tag tag s = + if not (known_tag tag) then raise Fail; + match Sub.heads 2 s with + | (' ' | '\t' | '\010'..'\013') :: _ + | [] | '>' :: _ | '/' :: '>' :: _ -> Lhtml (true, Hblank) + | _ -> raise Fail + +let ws1 s = + match Sub.head s with + | Some (' ' | '\t' | '\010'..'\013') -> + ws s + | Some _ | None -> + raise Fail + +let attribute_name s = + match Sub.head s with + | Some ('a'..'z' | 'A'..'Z' | '_' | ':') -> + let rec loop s = + match Sub.head s with + | Some ('a'..'z' | 'A'..'Z' | '_' | '.' | ':' | '0'..'9') -> + loop (Sub.tail s) + | Some _ | None -> + s + in + loop s + | Some _ | None -> + raise Fail + +let attribute_value s = + match Sub.head s with + | Some ('\'' | '"' as c) -> + let rec loop s = + match Sub.head s with + | Some c1 when c = c1 -> + Sub.tail s + | Some _ -> + loop (Sub.tail s) + | None -> + raise Fail + in + loop (Sub.tail s) + | Some _ -> + let rec loop first s = + match Sub.head s with + | Some (' ' | '\t' | '\010'..'\013' | '"' | '\'' | '=' | '<' | '>' | '`') + | None -> + if first then raise Fail; + s + | Some _ -> + loop false (Sub.tail s) + in + loop true s + | None -> + raise Fail + +let attribute s = + let s = ws1 s in + let s = attribute_name s in + let s = ws s in + match Sub.head s with + | Some '=' -> + let s = ws (Sub.tail s) in + attribute_value s + | Some _ | None -> + s + +let attributes s = + let rec loop s = + match attribute s with + | s -> loop s + | exception Fail -> s + in + loop s + +let open_tag s = + let s = attributes s in + let s = ws s in + let n = + match Sub.heads 2 s with + | '/' :: '>' :: _ -> 2 + | '>' :: _ -> 1 + | _ -> raise Fail + in + if not (is_empty (Sub.tails n s)) then raise Fail; + Lhtml (false, Hblank) + +let raw_html s = + match Sub.heads 10 s with + | '<' :: '?' :: _ -> + Lhtml (true, Hcontains ["?>"]) + | '<' :: '!' :: '-' :: '-' :: _ -> + Lhtml (true, Hcontains ["-->"]) + | '<' :: '!' :: '[' :: 'C' :: 'D' :: 'A' :: 'T' :: 'A' :: '[' :: _ -> + Lhtml (true, Hcontains ["]]>"]) + | '<' :: '!' :: _ -> + Lhtml (true, Hcontains [">"]) + | '<' :: '/' :: _ -> + let tag, s = tag_name (Sub.tails 2 s) in + (known_tag tag ||| closing_tag) s + | '<' :: _ -> + let tag, s = tag_name (Sub.tails 1 s) in + (special_tag tag ||| known_tag tag ||| open_tag) s + | _ -> + raise Fail + +let blank s = + if not (is_empty s) then raise Fail; + Lempty + +let tag_string s = + let buf = Buffer.create 17 in + let s, a = + match Sub.head ~rev:() s with + | Some '}' -> + attribute_string s + | _ -> + s, [] + in + let s = ws ~rev:() (ws s) in + let rec loop s = + match Sub.head s with + | Some (' ' | '\t' | '\010'..'\013') | None -> + Buffer.contents buf, a + | Some c -> + Buffer.add_char buf c; + loop (Sub.tail s) + in + loop (ws s) + +let def_list s = + let s = Sub.tail s in + match Sub.head (s) with + | Some (' ' | '\t' | '\010'..'\013') -> Ldef_list (String.trim (Sub.to_string s)) + | _ -> raise Fail + +let indented_code ind s = + if indent s + ind < 4 then raise Fail; + Lindented_code (Sub.offset (4 - ind) s) + +let parse s0 = + let ind, s = sp3 s0 in + match Sub.head s with + | Some '>' -> + let s = Sub.offset 1 s in + let s = if indent s > 0 then Sub.offset 1 s else s in + Lblockquote s + | Some '=' -> + setext_heading s + | Some '-' -> + (setext_heading ||| thematic_break ||| unordered_list_item ind) s + | Some ('_') -> + thematic_break s + | Some '#' -> + atx_heading s + | Some ('~' | '`') -> + fenced_code ind s + | Some '<' -> + raw_html s + | Some '*' -> + (thematic_break ||| unordered_list_item ind) s + | Some '+' -> + unordered_list_item ind s + | Some ('0'..'9') -> + ordered_list_item ind s + | Some ':' -> + def_list s + | Some _ -> + (blank ||| indented_code ind) s + | None -> + Lempty + +let parse s = + try parse s with Fail -> Lparagraph + +open P + +let is_empty st = + let off = pos st in + try + let rec loop () = + match next st with + | ' ' | '\t' | '\010'..'\013' -> loop () + | _ -> set_pos st off; false + in + loop () + with Fail -> + set_pos st off; + true + +let inline_attribute_string s = + let ppos = pos s in + ws s; + let a = + match peek s with + | Some '{' -> + let buf = Buffer.create 64 in + let rec loop s pos = + match peek s with + | Some '}' -> + junk s; + Some (Buffer.contents buf) + | None | Some '{' -> + set_pos s pos; None + | Some c -> + Buffer.add_char buf c; + junk s; + loop s pos + in + junk s; + loop s (pos s) + | _ -> + None + in + let attr = parse_attributes a in + if attr = [] + then + set_pos s ppos; + attr + +let entity buf st = + let p = pos st in + if next st <> '&' then raise Fail; + match peek st with + | Some '#' -> + junk st; + begin match peek st with + | Some ('x' | 'X') -> + junk st; + let rec aux n m = + if n > 8 then Buffer.add_string buf (range st p (pos st - p)) + else begin + match peek st with + | Some ('0'..'9' as c) -> + junk st; + aux (succ n) (m * 16 + Char.code c - Char.code '0') + | Some ('a'..'f' as c) -> + junk st; + aux (succ n) (m * 16 + Char.code c - Char.code 'a' + 10) + | Some ('A'..'F' as c) -> + junk st; + aux (succ n) (m * 16 + Char.code c - Char.code 'A' + 10) + | Some ';' -> + junk st; + if n = 0 then + Buffer.add_string buf (range st p (pos st - p)) + else + let u = if Uchar.is_valid m && m <> 0 then Uchar.of_int m else Uchar.rep in + Buffer.add_utf_8_uchar buf u + | Some _ | None -> + Buffer.add_string buf (range st p (pos st - p)) + end + in + aux 0 0 + | Some '0'..'9' -> + let rec aux n m = + if n > 8 then Buffer.add_string buf (range st p (pos st - p)) + else begin + match peek st with + | Some ('0'..'9' as c) -> + junk st; + aux (succ n) (m * 10 + Char.code c - Char.code '0') + | Some ';' -> + junk st; + if n = 0 then + Buffer.add_string buf (range st p (pos st - p)) + else begin + let u = if Uchar.is_valid m && m <> 0 then Uchar.of_int m else Uchar.rep in + Buffer.add_utf_8_uchar buf u + end + | Some _ | None -> + Buffer.add_string buf (range st p (pos st - p)) + end + in + aux 0 0 + | Some _ | None -> + Buffer.add_string buf (range st p (pos st - p)) + end + | Some ('0'..'9' | 'a'..'z' | 'A'..'Z') -> + let q = pos st in + let rec aux () = + match peek st with + | Some ('0'..'9' | 'a'..'z' | 'A'..'Z') -> + junk st; aux () + | Some ';' -> + let name = range st q (pos st - q) in + junk st; + begin match Entities.f name with + | [] -> + Buffer.add_string buf (range st p (pos st - p)) + | _ :: _ as cps -> + List.iter (Buffer.add_utf_8_uchar buf) cps + end + | Some _ | None -> + Buffer.add_string buf (range st p (pos st - p)) + in + aux () + | Some _ | None -> + Buffer.add_string buf (range st p (pos st - p)) + +let mk ?(attr = []) desc = + {Ast.il_desc = desc; il_attributes = attr} + +module Pre = struct + type delim = + | Ws + | Punct + | Other + + type emph_style = + | Star + | Underscore + + type link_kind = + | Img + | Url + + type t = + | Bang_left_bracket + | Left_bracket of link_kind + | Emph of delim * delim * emph_style * int + | R of inline + + let concat = function + | [x] -> x + | l -> mk (Concat l) + + let left_flanking = function + | Emph (_, Other, _, _) | Emph ((Ws | Punct), Punct, _, _) -> true + | _ -> false + + let right_flanking = function + | Emph (Other, _, _, _) | Emph (Punct, (Ws | Punct), _, _) -> true + | _ -> false + + let is_opener = function + | Emph (pre, _, Underscore, _) as x -> + left_flanking x && (not (right_flanking x) || pre = Punct) + | Emph (_, _, Star, _) as x -> + left_flanking x + | _ -> + false + + let is_closer = function + | Emph (_, post, Underscore, _) as x -> + right_flanking x && (not (left_flanking x) || post = Punct) + | Emph (_, _, Star, _) as x -> + right_flanking x + | _ -> + false + + let classify_delim = function + | '!' | '"' | '#' | '$' | '%' + | '&' | '\'' | '(' | ')' | '*' | '+' + | ',' | '-' | '.' | '/' | ':' | ';' + | '<' | '=' | '>' | '?' | '@' | '[' + | '\\' | ']' | '^' | '_' | '`' | '{' + | '|' | '}' | '~' -> Punct + | ' ' | '\t' | '\010'..'\013' -> Ws + | _ -> Other + + let to_r = function + | Bang_left_bracket -> mk (Text "![") + | Left_bracket Img -> mk (Text "![") + | Left_bracket Url -> mk (Text "[") + | Emph (_, _, Star, n) -> mk (Text (String.make n '*')) + | Emph (_, _, Underscore, n) -> mk (Text (String.make n '_')) + | R x -> x + + let rec parse_emph = function + | Emph (pre, _, q1, n1) as x :: xs when is_opener x -> + let rec loop acc = function + | Emph (_, post, q2, n2) as x :: xs when is_closer x && q1 = q2 -> + let xs = + if n1 >= 2 && n2 >= 2 then + if n2 > 2 then Emph (Punct, post, q2, n2-2) :: xs else xs + else + if n2 > 1 then Emph (Punct, post, q2, n2-1) :: xs else xs + in + let r = + let il = concat (List.map to_r (parse_emph (List.rev acc))) in + if n1 >= 2 && n2 >= 2 then + R (mk (Strong il)) :: xs + else + R (mk (Emph il)) :: xs + in + let r = + if n1 >= 2 && n2 >= 2 then + if n1 > 2 then Emph (pre, Punct, q1, n1-2) :: r else r + else + if n1 > 1 then Emph (pre, Punct, q1, n1-1) :: r else r + in + parse_emph r + | Emph _ as x :: xs1 as xs when is_opener x -> + let xs' = parse_emph xs in + if xs' = xs then loop (x :: acc) xs1 else loop acc xs' + | x :: xs -> + loop (x :: acc) xs + | [] -> + x :: List.rev acc + in + loop [] xs + | x :: xs -> + x :: parse_emph xs + | [] -> + [] + + let parse_emph xs = + concat (List.map to_r (parse_emph xs)) +end + +let escape buf st = + if next st <> '\\' then raise Fail; + match peek st with + | Some c when is_punct c -> + junk st; Buffer.add_char buf c + | Some _ | None -> + Buffer.add_char buf '\\' + +let link_label allow_balanced_brackets st = + if peek_exn st <> '[' then raise Fail; + junk st; + let buf = Buffer.create 17 in + let rec loop n nonempty = + match peek_exn st with + | ']' when n = 0 -> + junk st; + if not nonempty then raise Fail; + Buffer.contents buf + | ']' as c -> + assert (n > 0); + junk st; + Buffer.add_char buf c; + loop (pred n) true + | '\\' as c -> + junk st; Buffer.add_char buf c; + begin match peek_exn st with + | c when is_punct c -> + junk st; Buffer.add_char buf c + | _ -> + () + end; + loop n true + | '[' when not allow_balanced_brackets -> + raise Fail + | '[' as c -> + junk st; Buffer.add_char buf c; loop (succ n) true + | ' ' | '\t' | '\010'..'\013' as c -> + junk st; Buffer.add_char buf c; loop n nonempty + | _ as c -> + junk st; Buffer.add_char buf c; loop n true + in + loop 0 false + +let normalize s = + let buf = Buffer.create (String.length s) in + let rec loop start seen_ws i = + if i >= String.length s then + Buffer.contents buf + else begin + match s.[i] with + | ' ' | '\t' | '\010'..'\013' -> + loop start true (succ i) + | _ as c -> + if not start && seen_ws then Buffer.add_char buf ' '; + Buffer.add_char buf (Char.lowercase_ascii c); + loop false false (succ i) + end + in + loop true false 0 + +let tag_name st = + match peek_exn st with + | 'a'..'z' | 'A'..'Z' -> + junk st; + let rec loop () = + match peek st with + | Some ('a'..'z' | 'A'..'Z' | '0'..'9' | '-') -> + junk st; loop () + | Some _ | None -> () + in + loop () + | _ -> + raise Fail + +let ws_buf buf st = + let rec loop () = + match peek st with + | Some (' ' | '\t' | '\010'..'\013' as c) -> + Buffer.add_char buf c; junk st; loop () + | Some _ | None -> + () + in + loop () + +let closing_tag st = + let start = pos st in + if next st <> '<' then raise Fail; + if next st <> '/' then raise Fail; + tag_name st; + ws st; + if next st <> '>' then raise Fail; + range st start (pos st - start) + +let list p st = + let rec loop () = + match protect p st with + | () -> loop () + | exception Fail -> () + in + loop () + +let single_quoted_attribute st = + if next st <> '\'' then raise Fail; + let rec loop () = + match peek_exn st with + | '\'' -> + junk st + (* | '&' -> *) + (* entity buf st; loop () *) + | _ -> + junk st; loop () + in + loop () + +let double_quoted_attribute st = + if next st <> '"' then raise Fail; + let rec loop () = + match peek_exn st with + | '"' -> + junk st + (* | '&' -> *) + (* entity buf st; loop () *) + | _ -> + junk st; loop () + in + loop () + +let unquoted_attribute st = + let rec loop n = + match peek_exn st with + | ' ' | '\t' | '\010'..'\013' | '"' | '\'' | '=' | '<' | '>' | '`' -> + if n = 0 then raise Fail + (* | '&' -> *) + (* entity buf st; loop () *) + | _ -> + junk st; loop (succ n) + in + loop 0 + +let attribute_value st = + match peek_exn st with + | '\'' -> single_quoted_attribute st + | '"' -> double_quoted_attribute st + | _ -> unquoted_attribute st + +let attribute_name st = + match peek_exn st with + | 'a'..'z' | 'A'..'Z' | '_' | ':' -> + junk st; + let rec loop () = + match peek st with + | Some ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '.' | ':' | '-') -> + junk st; loop () + | Some _ | None -> + () + in + loop () + | _ -> + raise Fail + +let option d p st = + match protect p st with + | r -> r + | exception Fail -> d + +let some p st = + Some (p st) + +let attribute_value_specification = + ws >>> char '=' >>> ws >>> attribute_value + +let ws1_buf buf st = + match peek st with + | Some (' ' | '\t' | '\010'..'\013') -> + ws_buf buf st + | Some _ | None -> + raise Fail + +let attribute st = + ws1 st; + attribute_name st; + option () attribute_value_specification st + +let open_tag st = + let start = pos st in + if next st <> '<' then raise Fail; + tag_name st; + list attribute st; + ws st; + begin match peek_exn st with + | '/' -> junk st + | _ -> () + end; + if next st <> '>' then raise Fail; + range st start (pos st - start) + +let html_comment st = + let buf = Buffer.create 17 in + if next st <> '<' then raise Fail; + if next st <> '!' then raise Fail; + if next st <> '-' then raise Fail; + if next st <> '-' then raise Fail; + Buffer.add_string buf ""; + Buffer.contents buf + | '>' when start -> + raise Fail + | _ -> + Buffer.add_char buf c; loop false + end + | '>' when start -> + raise Fail + | '&' -> + entity buf st; loop false + | _ as c -> + junk st; Buffer.add_char buf c; loop false + in + loop true + +let processing_instruction st = + let buf = Buffer.create 17 in + if next st <> '<' then raise Fail; + if next st <> '?' then raise Fail; + Buffer.add_string buf " + junk st; + begin match peek_exn st with + | '>' -> + junk st; Buffer.add_string buf "?>"; Buffer.contents buf + | _ -> + Buffer.add_char buf c; loop () + end + | '&' -> + entity buf st; loop () + | _ as c -> + junk st; Buffer.add_char buf c; loop () + in + loop () + +let cdata_section st = + let buf = Buffer.create 17 in + if next st <> '<' then raise Fail; + if next st <> '!' then raise Fail; + if next st <> '[' then raise Fail; + if next st <> 'C' then raise Fail; + if next st <> 'D' then raise Fail; + if next st <> 'A' then raise Fail; + if next st <> 'T' then raise Fail; + if next st <> 'A' then raise Fail; + if next st <> '[' then raise Fail; + Buffer.add_string buf " + junk st; + begin match peek_exn st with + | ']' as c1 -> + junk st; + begin match peek_exn st with + | '>' -> + junk st; Buffer.add_string buf "]]>"; Buffer.contents buf + | _ -> + Buffer.add_char buf c; Buffer.add_char buf c1; loop () + end + | _ -> + Buffer.add_char buf c; loop () + end + | '&' -> + entity buf st; loop () + | _ as c -> + junk st; Buffer.add_char buf c; loop () + in + loop () + +let declaration st = + let buf = Buffer.create 17 in + if next st <> '<' then raise Fail; + if next st <> '!' then raise Fail; + Buffer.add_string buf " + let rec loop () = + match peek_exn st with + | 'A'..'Z' as c -> + junk st; Buffer.add_char buf c; loop () + | ' ' | '\t' | '\010'..'\013' -> + ws1_buf buf st; + let rec loop () = + match peek_exn st with + | '>' as c -> + junk st; Buffer.add_char buf c; Buffer.contents buf + | '&' -> + entity buf st; loop () + | _ as c -> + junk st; Buffer.add_char buf c; loop () + in + loop () + | _ -> + raise Fail + in + loop () + | _ -> + raise Fail + + +let link_destination st = + let buf = Buffer.create 17 in + match peek_exn st with + | '<' -> + junk st; + let rec loop () = + match peek_exn st with + | '>' -> + junk st; Buffer.contents buf + | ' ' | '\t' | '\010'..'\013' | '<' -> + raise Fail + | '\\' -> + escape buf st; loop () + | '&' -> + entity buf st; loop () + | _ as c -> + junk st; Buffer.add_char buf c; loop () + in + loop () + | _ -> + let rec loop n = + match peek st with + | Some ('(' as c) -> + junk st; Buffer.add_char buf c; loop (succ n) + | Some ')' when n = 0 -> + if Buffer.length buf = 0 then raise Fail; + Buffer.contents buf + | Some (')' as c) -> + junk st; Buffer.add_char buf c; loop (pred n) + | Some '\\' -> + escape buf st; loop n + | Some '&' -> + entity buf st; loop n + | Some (' ' | '\t' | '\x00'..'\x1F' | '\x7F' | '\x80'..'\x9F') | None -> + if n > 0 || Buffer.length buf = 0 then raise Fail; + Buffer.contents buf + | Some c -> + junk st; Buffer.add_char buf c; loop n + in + loop 0 + +let eol st = + match peek st with + | Some '\n' -> junk st + | Some _ -> raise Fail + | None -> () + +let link_title st = + let buf = Buffer.create 17 in + match peek_exn st with + | '\'' | '"' as c -> + junk st; + let rec loop () = + match peek_exn st with + | '\\' -> + escape buf st; loop () + | '&' -> + entity buf st; loop () + | _ as c1 when c = c1 -> + junk st; Buffer.contents buf + | _ as c1 -> + junk st; Buffer.add_char buf c1; loop () + in + loop () + | '(' -> + junk st; + let rec loop () = + match peek_exn st with + | '\\' -> + escape buf st; loop () + | '&' -> + entity buf st; loop () + | ')' -> + junk st; + Buffer.contents buf + | _ as c -> + junk st; Buffer.add_char buf c; loop () + in + loop () + | _ -> + raise Fail + +let space st = + match peek_exn st with + | ' ' -> junk st + | _ -> raise Fail + +let many p st = + try + while true do p st done + with Fail -> + () + +let scheme st = + match peek_exn st with + | 'a'..'z' | 'A'..'Z' -> + let rec loop n = + if n < 32 then begin + match peek st with + | Some ('a'..'z' | 'A'..'Z' | '0'..'9' | '+' | '.' | '-') -> + junk st; loop (succ n) + | Some _ | None -> + n + end else n + in + let n = loop 0 in + if n < 2 then raise Fail + | _ -> + raise Fail + +let absolute_uri st = + let p = pos st in + scheme st; + if next st <> ':' then raise Fail; + let rec loop () = + match peek st with + | Some (' ' | '\t' | '\010'..'\013' | '\x00'..'\x1F' | '\x7F'..'\x9F' | '<' | '>') | None -> + let txt = range st p (pos st - p) in + txt, txt + | Some _ -> + junk st; loop () + in + loop () + +let email_address st = + let p = pos st in + let rec loop n = + match peek_exn st with + | 'a'..'z' | 'A'..'Z' | '0'..'9' + | '.' | '!' | '#' | '$' | '%' | '&' | '\'' | '*' + | '+' | '/' | '=' | '?' | '^' | '_' | '`' | '{' | '|' + | '}' | '~' | '-' -> + junk st; loop (succ n) + | '@' -> + junk st; + let label st = + let let_dig st = + match peek_exn st with + | 'a'..'z' | 'A'..'Z' | '0'..'9' -> junk st; false + | '-' -> junk st; true + | _ -> raise Fail + in + if let_dig st then raise Fail; + let rec loop last = + match let_dig st with + | r -> + loop r + | exception Fail -> + if last then raise Fail + in + loop false + in + label st; + list (char '.' >>> label) st; + let txt = range st p (pos st - p) in + txt, "mailto:" ^ txt + | _ -> + raise Fail + in + loop 0 + +let autolink st = + match peek_exn st with + | '<' -> + junk st; + let label, destination = (absolute_uri ||| email_address) st in + if next st <> '>' then raise Fail; + {Ast.label; destination; title = None} + | _ -> + raise Fail + +let inline_link = + char '(' >>> ws >>> + option ("", None) + (pair link_destination (option None (ws1 >>> some link_title))) + <<< ws <<< char ')' + +let rec inline defs st = + let buf = Buffer.create 0 in + let get_buf () = + let s = Buffer.contents buf in + Buffer.clear buf; + s + in + let text acc = + if Buffer.length buf = 0 then + acc + else + Pre.R (mk (Text (get_buf ()))) :: acc + in + let rec reference_link kind acc st = + let off0 = pos st in + match protect (link_label true) st with + | lab -> + let off1 = pos st in + let lab1 = inline defs (of_string lab) in + let reflink lab' = + let s = normalize lab' in + match List.find_opt (fun ({label; _}, _) -> label = s) defs with + | Some (def, attr) -> + let r = + let def = {def with label = lab1} in + match kind with Pre.Img -> Image def | Url -> Link def + in + loop (Pre.R (mk ~attr r) :: text acc) st + | None -> + if kind = Img then Buffer.add_char buf '!'; + Buffer.add_char buf '['; + let acc = Pre.R lab1 :: text acc in + Buffer.add_char buf ']'; + set_pos st off1; + loop acc st + in + begin match peek st with + | Some '[' -> + if peek_after '\000' st = ']' then + (junk st; junk st; reflink lab) + else begin + match protect (link_label false) st with + | _ -> + set_pos st off0; junk st; loop (Left_bracket kind :: text acc) st + | exception Fail -> + reflink lab + end + | Some '(' -> + begin match protect inline_link st with + | _ -> + set_pos st off0; junk st; loop (Left_bracket kind :: text acc) st + | exception Fail -> + reflink lab + end + | Some _ | None -> + reflink lab + end + | exception Fail -> + junk st; loop (Left_bracket kind :: text acc) st + and loop acc st = + match peek_exn st with + | '<' as c -> + begin match protect autolink st with + | def -> + let def = {def with label = mk (Text def.label)} in + let attr = inline_attribute_string st in + loop (Pre.R (mk ~attr (Link def)) :: text acc) st + | exception Fail -> + begin match + protect (closing_tag ||| open_tag ||| html_comment ||| + declaration ||| cdata_section ||| processing_instruction) st + with + | tag -> + loop (Pre.R (mk (Html tag)) :: text acc) st + | exception Fail -> + junk st; Buffer.add_char buf c; loop acc st + end + end + | '\n' -> + junk st; sp st; loop (Pre.R (mk Soft_break) :: text acc) st + | ' ' as c -> + junk st; + begin match peek st with + | Some ' ' -> + begin match protect (many space >>> char '\n' >>> many space) st with + | () -> + loop (Pre.R (mk Hard_break) :: text acc) st + | exception Fail -> + junk st; + Buffer.add_string buf " "; loop acc st + end + | Some '\n' -> + loop acc st + | Some _ | None -> + Buffer.add_char buf c; loop acc st + end + | '`' -> + let pos = pos st in + let rec loop2 n = + match peek st with + | Some '`' -> + junk st; loop2 (succ n) + | Some _ -> + let acc = text acc in + let bufcode = Buffer.create 17 in + let finish () = + let content = Buffer.contents bufcode in + let content = + if String.length content >= 2 && + content.[0] = ' ' && + content.[String.length content - 1] = ' ' (* FIXME not fully whitespace *) + then + String.sub content 1 (String.length content - 2) + else + content + in + let attr = inline_attribute_string st in + loop (Pre.R (mk ~attr (Code content)) :: acc) st + in + let rec loop3 start m = + match peek st with + | Some '`' -> + junk st; loop3 start (succ m) + | Some (' ' | '\t' | '\010'..'\013' as c) -> + if m = n then + finish () + else begin + if m > 0 then Buffer.add_string bufcode (String.make m '`'); + Buffer.add_char bufcode (if c = '\010' then ' ' else c); + junk st; loop3 (start && m = 0) 0 + end + | Some c -> + if m = n then + finish () + else begin + junk st; + (* if seen_ws then Buffer.add_char bufcode ' '; *) + if m > 0 then Buffer.add_string bufcode (String.make m '`'); + Buffer.add_char bufcode c; + loop3 false 0 + end + | None -> + if m = n then + finish () + else begin + Buffer.add_string buf (range st pos n); + set_pos st (pos + n); + loop acc st + end + in + loop3 true 0 + | None -> + Buffer.add_string buf (String.make n '`'); loop acc st + in + loop2 0 + | '\\' as c -> + junk st; + begin match peek st with + | Some '\n' -> + junk st; loop (Pre.R (mk Hard_break) :: text acc) st + | Some c when is_punct c -> + junk st; Buffer.add_char buf c; loop acc st + | Some _ | None -> + Buffer.add_char buf c; loop acc st + end + | '!' as c -> + junk st; + begin match peek st with + | Some '[' -> + reference_link Img (text acc) st + | Some _ | None -> + Buffer.add_char buf c; loop acc st + end + | '&' -> + entity buf st; loop acc st + | ']' -> + junk st; + let acc = text acc in + let rec aux seen_link xs = function + | Pre.Left_bracket Url :: _ when seen_link -> + Buffer.add_char buf ']'; loop acc st + | Left_bracket k :: acc' -> + begin match peek st with + | Some '(' -> + begin match protect inline_link st with + | destination, title -> + let r = + let label = Pre.parse_emph xs in + let def = {label; destination; title} in + match k with + | Img -> Image def + | Url -> Link def + in + let attr = inline_attribute_string st in + loop (Pre.R (mk ~attr r) :: acc') st + | exception Fail -> + Buffer.add_char buf ']'; loop acc st + end + | Some '[' -> + let label = Pre.parse_emph xs in + let off1 = pos st in + begin match link_label false st with + | lab -> + let s = normalize lab in + begin match List.find_opt (fun ({label; _}, _) -> label = s) defs with + | Some (def, attr) -> + let def = {def with label} in + let r = match k with Img -> Image def | Url -> Link def in + loop (Pre.R (mk ~attr r) :: acc') st + | None -> + if k = Img then Buffer.add_char buf '!'; + Buffer.add_char buf '['; + let acc = Pre.R label :: text acc' in + Buffer.add_char buf ']'; + set_pos st off1; + loop acc st + end + | exception Fail -> + if k = Img then Buffer.add_char buf '!'; + Buffer.add_char buf '['; + let acc = Pre.R label :: text acc in + Buffer.add_char buf ']'; + set_pos st off1; + loop acc st + end + | Some _ | None -> + Buffer.add_char buf ']'; loop acc st + end + | Pre.R ({il_desc = Link _; _}) as x :: acc' -> + aux true (x :: xs) acc' + | x :: acc' -> + aux seen_link (x :: xs) acc' + | [] -> + Buffer.add_char buf ']'; loop acc st + in + aux false [] acc + | '[' -> + reference_link Url acc st + | '*' | '_' as c -> + let pre = peek_before ' ' st in + let f post n st = + let pre = pre |> Pre.classify_delim in + let post = post |> Pre.classify_delim in + let e = if c = '*' then Pre.Star else Pre.Underscore in + loop (Pre.Emph (pre, post, e, n) :: text acc) st + in + let rec aux n = + match peek st with + | Some c1 when c1 = c -> junk st; aux (succ n) + | Some c1 -> f c1 n st + | None -> f ' ' n st + in + aux 0 + | _ as c -> + junk st; Buffer.add_char buf c; loop acc st + | exception Fail -> + Pre.parse_emph (List.rev (text acc)) + in + loop [] st + +let sp3 st = + match peek_exn st with + | ' ' -> + junk st; + begin match peek_exn st with + | ' ' -> + junk st; + begin match peek_exn st with + | ' ' -> junk st; 3 + | _ -> 2 + | exception Fail -> 2 + end + | _ -> 1 + | exception Fail -> 1 + end + | _ -> 0 + | exception Fail -> 0 + +let link_reference_definition st = + let ws st = + let rec loop seen_nl = + match peek st with + | Some (' ' | '\t' | '\011'..'\013') -> junk st; loop seen_nl + | Some '\n' when not seen_nl -> junk st; loop true + | Some _ | None -> () + in + loop false + in + let ws1 st = + match next st with + | ' ' | '\t' | '\010'..'\013' -> ws st + | _ -> raise Fail + in + ignore (sp3 st); + let label = link_label false st in + if next st <> ':' then raise Fail; + ws st; + let destination = link_destination st in + let attributes = inline_attribute_string st in + match protect (ws1 >>> link_title <<< sp <<< eol) st with + | title -> + {Ast.label; destination; title = Some title}, attributes + | exception Fail -> + (sp >>> eol) st; + {Ast.label; destination; title = None}, attributes + +let link_reference_definitions st = + let rec loop acc = + match protect link_reference_definition st with + | def -> + loop (def :: acc) + | exception Fail -> + acc, pos st + in + loop [] diff --git a/src/reason-parser/vendor/omd/src/sexp.ml b/src/reason-parser/vendor/omd/src/sexp.ml new file mode 100644 index 000000000..cbca52f9c --- /dev/null +++ b/src/reason-parser/vendor/omd/src/sexp.ml @@ -0,0 +1,84 @@ +open Ast + +type t = + | Atom of string + | List of t list + +let atom s = Atom s + +let rec link_def : 'a. ('a -> t) -> 'a link_def -> t = + fun f {label; destination; title; _} -> + let title = match title with Some title -> [Atom title] | None -> [] in + List (Atom "link-def" :: f label :: Atom destination :: title) + +and inline {il_desc; _} = + match il_desc with + | Concat xs -> + List (Atom "concat" :: List.map inline xs) + | Text s -> + Atom s + | Emph il -> + List [Atom "emph"; inline il] + | Strong il -> + List [Atom "strong"; inline il] + | Code _ -> + Atom "code" + | Hard_break -> + Atom "hard-break" + | Soft_break -> + Atom "soft-break" + | Link def -> + List [Atom "url"; link_def inline def] + | Html s -> + List [Atom "html"; Atom s] + | Image _ -> + Atom "img" + +let rec block {bl_desc; bl_attributes = _} = + match bl_desc with + | Paragraph x -> + List [Atom "paragraph"; inline x] + | List (_, _, bls) -> + List (Atom "list" :: List.map (fun xs -> List (Atom "list-item" :: List.map block xs)) bls) + | Blockquote xs -> + List (Atom "blockquote" :: List.map block xs) + | Thematic_break -> + Atom "thematic-break" + | Heading (level, text) -> + List [Atom "heading"; Atom (string_of_int level); inline text] + | Code_block (info, _) -> + List [Atom "code-block"; Atom info] + | Html_block s -> + List [Atom "html"; Atom s] + | Link_def {label; destination; _} -> + List [Atom "link-def"; Atom label; Atom destination] + | Definition_list l -> + List [Atom "def-list"; + List (List.map (fun elt -> + List [inline elt.term; + List (List.map inline elt.defs)]) l)] + +let create ast = + List (List.map block ast) + +let needs_quotes s = + let rec loop i = + if i >= String.length s then + false + else begin + match s.[i] with + | ' ' | '\t' | '\x00'..'\x1F' | '\x7F'..'\x9F' -> + true + | _ -> + loop (succ i) + end + in + loop 0 + +let rec print ppf = function + | Atom s when needs_quotes s -> + Format.fprintf ppf "%S" s + | Atom s -> + Format.pp_print_string ppf s + | List l -> + Format.fprintf ppf "@[<1>(%a)@]" (Format.pp_print_list ~pp_sep:Format.pp_print_space print) l diff --git a/src/reason-parser/vendor/omd/tools/dune b/src/reason-parser/vendor/omd/tools/dune new file mode 100644 index 000000000..f6b9b7f56 --- /dev/null +++ b/src/reason-parser/vendor/omd/tools/dune @@ -0,0 +1,2 @@ +(executable + (name gen_entities)) diff --git a/src/reason-parser/vendor/omd/tools/entities.json b/src/reason-parser/vendor/omd/tools/entities.json new file mode 100644 index 000000000..557170b41 --- /dev/null +++ b/src/reason-parser/vendor/omd/tools/entities.json @@ -0,0 +1,2233 @@ +{ + "Æ": { "codepoints": [198], "characters": "\u00C6" }, + "Æ": { "codepoints": [198], "characters": "\u00C6" }, + "&": { "codepoints": [38], "characters": "\u0026" }, + "&": { "codepoints": [38], "characters": "\u0026" }, + "Á": { "codepoints": [193], "characters": "\u00C1" }, + "Á": { "codepoints": [193], "characters": "\u00C1" }, + "Ă": { "codepoints": [258], "characters": "\u0102" }, + "Â": { "codepoints": [194], "characters": "\u00C2" }, + "Â": { "codepoints": [194], "characters": "\u00C2" }, + "А": { "codepoints": [1040], "characters": "\u0410" }, + "𝔄": { "codepoints": [120068], "characters": "\uD835\uDD04" }, + "À": { "codepoints": [192], "characters": "\u00C0" }, + "À": { "codepoints": [192], "characters": "\u00C0" }, + "Α": { "codepoints": [913], "characters": "\u0391" }, + "Ā": { "codepoints": [256], "characters": "\u0100" }, + "⩓": { "codepoints": [10835], "characters": "\u2A53" }, + "Ą": { "codepoints": [260], "characters": "\u0104" }, + "𝔸": { "codepoints": [120120], "characters": "\uD835\uDD38" }, + "⁡": { "codepoints": [8289], "characters": "\u2061" }, + "Å": { "codepoints": [197], "characters": "\u00C5" }, + "Å": { "codepoints": [197], "characters": "\u00C5" }, + "𝒜": { "codepoints": [119964], "characters": "\uD835\uDC9C" }, + "≔": { "codepoints": [8788], "characters": "\u2254" }, + "Ã": { "codepoints": [195], "characters": "\u00C3" }, + "Ã": { "codepoints": [195], "characters": "\u00C3" }, + "Ä": { "codepoints": [196], "characters": "\u00C4" }, + "Ä": { "codepoints": [196], "characters": "\u00C4" }, + "∖": { "codepoints": [8726], "characters": "\u2216" }, + "⫧": { "codepoints": [10983], "characters": "\u2AE7" }, + "⌆": { "codepoints": [8966], "characters": "\u2306" }, + "Б": { "codepoints": [1041], "characters": "\u0411" }, + "∵": { "codepoints": [8757], "characters": "\u2235" }, + "ℬ": { "codepoints": [8492], "characters": "\u212C" }, + "Β": { "codepoints": [914], "characters": "\u0392" }, + "𝔅": { "codepoints": [120069], "characters": "\uD835\uDD05" }, + "𝔹": { "codepoints": [120121], "characters": "\uD835\uDD39" }, + "˘": { "codepoints": [728], "characters": "\u02D8" }, + "ℬ": { "codepoints": [8492], "characters": "\u212C" }, + "≎": { "codepoints": [8782], "characters": "\u224E" }, + "Ч": { "codepoints": [1063], "characters": "\u0427" }, + "©": { "codepoints": [169], "characters": "\u00A9" }, + "©": { "codepoints": [169], "characters": "\u00A9" }, + "Ć": { "codepoints": [262], "characters": "\u0106" }, + "⋒": { "codepoints": [8914], "characters": "\u22D2" }, + "ⅅ": { "codepoints": [8517], "characters": "\u2145" }, + "ℭ": { "codepoints": [8493], "characters": "\u212D" }, + "Č": { "codepoints": [268], "characters": "\u010C" }, + "Ç": { "codepoints": [199], "characters": "\u00C7" }, + "Ç": { "codepoints": [199], "characters": "\u00C7" }, + "Ĉ": { "codepoints": [264], "characters": "\u0108" }, + "∰": { "codepoints": [8752], "characters": "\u2230" }, + "Ċ": { "codepoints": [266], "characters": "\u010A" }, + "¸": { "codepoints": [184], "characters": "\u00B8" }, + "·": { "codepoints": [183], "characters": "\u00B7" }, + "ℭ": { "codepoints": [8493], "characters": "\u212D" }, + "Χ": { "codepoints": [935], "characters": "\u03A7" }, + "⊙": { "codepoints": [8857], "characters": "\u2299" }, + "⊖": { "codepoints": [8854], "characters": "\u2296" }, + "⊕": { "codepoints": [8853], "characters": "\u2295" }, + "⊗": { "codepoints": [8855], "characters": "\u2297" }, + "∲": { "codepoints": [8754], "characters": "\u2232" }, + "”": { "codepoints": [8221], "characters": "\u201D" }, + "’": { "codepoints": [8217], "characters": "\u2019" }, + "∷": { "codepoints": [8759], "characters": "\u2237" }, + "⩴": { "codepoints": [10868], "characters": "\u2A74" }, + "≡": { "codepoints": [8801], "characters": "\u2261" }, + "∯": { "codepoints": [8751], "characters": "\u222F" }, + "∮": { "codepoints": [8750], "characters": "\u222E" }, + "ℂ": { "codepoints": [8450], "characters": "\u2102" }, + "∐": { "codepoints": [8720], "characters": "\u2210" }, + "∳": { "codepoints": [8755], "characters": "\u2233" }, + "⨯": { "codepoints": [10799], "characters": "\u2A2F" }, + "𝒞": { "codepoints": [119966], "characters": "\uD835\uDC9E" }, + "⋓": { "codepoints": [8915], "characters": "\u22D3" }, + "≍": { "codepoints": [8781], "characters": "\u224D" }, + "ⅅ": { "codepoints": [8517], "characters": "\u2145" }, + "⤑": { "codepoints": [10513], "characters": "\u2911" }, + "Ђ": { "codepoints": [1026], "characters": "\u0402" }, + "Ѕ": { "codepoints": [1029], "characters": "\u0405" }, + "Џ": { "codepoints": [1039], "characters": "\u040F" }, + "‡": { "codepoints": [8225], "characters": "\u2021" }, + "↡": { "codepoints": [8609], "characters": "\u21A1" }, + "⫤": { "codepoints": [10980], "characters": "\u2AE4" }, + "Ď": { "codepoints": [270], "characters": "\u010E" }, + "Д": { "codepoints": [1044], "characters": "\u0414" }, + "∇": { "codepoints": [8711], "characters": "\u2207" }, + "Δ": { "codepoints": [916], "characters": "\u0394" }, + "𝔇": { "codepoints": [120071], "characters": "\uD835\uDD07" }, + "´": { "codepoints": [180], "characters": "\u00B4" }, + "˙": { "codepoints": [729], "characters": "\u02D9" }, + "˝": { "codepoints": [733], "characters": "\u02DD" }, + "`": { "codepoints": [96], "characters": "\u0060" }, + "˜": { "codepoints": [732], "characters": "\u02DC" }, + "⋄": { "codepoints": [8900], "characters": "\u22C4" }, + "ⅆ": { "codepoints": [8518], "characters": "\u2146" }, + "𝔻": { "codepoints": [120123], "characters": "\uD835\uDD3B" }, + "¨": { "codepoints": [168], "characters": "\u00A8" }, + "⃜": { "codepoints": [8412], "characters": "\u20DC" }, + "≐": { "codepoints": [8784], "characters": "\u2250" }, + "∯": { "codepoints": [8751], "characters": "\u222F" }, + "¨": { "codepoints": [168], "characters": "\u00A8" }, + "⇓": { "codepoints": [8659], "characters": "\u21D3" }, + "⇐": { "codepoints": [8656], "characters": "\u21D0" }, + "⇔": { "codepoints": [8660], "characters": "\u21D4" }, + "⫤": { "codepoints": [10980], "characters": "\u2AE4" }, + "⟸": { "codepoints": [10232], "characters": "\u27F8" }, + "⟺": { "codepoints": [10234], "characters": "\u27FA" }, + "⟹": { "codepoints": [10233], "characters": "\u27F9" }, + "⇒": { "codepoints": [8658], "characters": "\u21D2" }, + "⊨": { "codepoints": [8872], "characters": "\u22A8" }, + "⇑": { "codepoints": [8657], "characters": "\u21D1" }, + "⇕": { "codepoints": [8661], "characters": "\u21D5" }, + "∥": { "codepoints": [8741], "characters": "\u2225" }, + "↓": { "codepoints": [8595], "characters": "\u2193" }, + "⤓": { "codepoints": [10515], "characters": "\u2913" }, + "⇵": { "codepoints": [8693], "characters": "\u21F5" }, + "̑": { "codepoints": [785], "characters": "\u0311" }, + "⥐": { "codepoints": [10576], "characters": "\u2950" }, + "⥞": { "codepoints": [10590], "characters": "\u295E" }, + "↽": { "codepoints": [8637], "characters": "\u21BD" }, + "⥖": { "codepoints": [10582], "characters": "\u2956" }, + "⥟": { "codepoints": [10591], "characters": "\u295F" }, + "⇁": { "codepoints": [8641], "characters": "\u21C1" }, + "⥗": { "codepoints": [10583], "characters": "\u2957" }, + "⊤": { "codepoints": [8868], "characters": "\u22A4" }, + "↧": { "codepoints": [8615], "characters": "\u21A7" }, + "⇓": { "codepoints": [8659], "characters": "\u21D3" }, + "𝒟": { "codepoints": [119967], "characters": "\uD835\uDC9F" }, + "Đ": { "codepoints": [272], "characters": "\u0110" }, + "Ŋ": { "codepoints": [330], "characters": "\u014A" }, + "Ð": { "codepoints": [208], "characters": "\u00D0" }, + "Ð": { "codepoints": [208], "characters": "\u00D0" }, + "É": { "codepoints": [201], "characters": "\u00C9" }, + "É": { "codepoints": [201], "characters": "\u00C9" }, + "Ě": { "codepoints": [282], "characters": "\u011A" }, + "Ê": { "codepoints": [202], "characters": "\u00CA" }, + "Ê": { "codepoints": [202], "characters": "\u00CA" }, + "Э": { "codepoints": [1069], "characters": "\u042D" }, + "Ė": { "codepoints": [278], "characters": "\u0116" }, + "𝔈": { "codepoints": [120072], "characters": "\uD835\uDD08" }, + "È": { "codepoints": [200], "characters": "\u00C8" }, + "È": { "codepoints": [200], "characters": "\u00C8" }, + "∈": { "codepoints": [8712], "characters": "\u2208" }, + "Ē": { "codepoints": [274], "characters": "\u0112" }, + "◻": { "codepoints": [9723], "characters": "\u25FB" }, + "▫": { "codepoints": [9643], "characters": "\u25AB" }, + "Ę": { "codepoints": [280], "characters": "\u0118" }, + "𝔼": { "codepoints": [120124], "characters": "\uD835\uDD3C" }, + "Ε": { "codepoints": [917], "characters": "\u0395" }, + "⩵": { "codepoints": [10869], "characters": "\u2A75" }, + "≂": { "codepoints": [8770], "characters": "\u2242" }, + "⇌": { "codepoints": [8652], "characters": "\u21CC" }, + "ℰ": { "codepoints": [8496], "characters": "\u2130" }, + "⩳": { "codepoints": [10867], "characters": "\u2A73" }, + "Η": { "codepoints": [919], "characters": "\u0397" }, + "Ë": { "codepoints": [203], "characters": "\u00CB" }, + "Ë": { "codepoints": [203], "characters": "\u00CB" }, + "∃": { "codepoints": [8707], "characters": "\u2203" }, + "ⅇ": { "codepoints": [8519], "characters": "\u2147" }, + "Ф": { "codepoints": [1060], "characters": "\u0424" }, + "𝔉": { "codepoints": [120073], "characters": "\uD835\uDD09" }, + "◼": { "codepoints": [9724], "characters": "\u25FC" }, + "▪": { "codepoints": [9642], "characters": "\u25AA" }, + "𝔽": { "codepoints": [120125], "characters": "\uD835\uDD3D" }, + "∀": { "codepoints": [8704], "characters": "\u2200" }, + "ℱ": { "codepoints": [8497], "characters": "\u2131" }, + "ℱ": { "codepoints": [8497], "characters": "\u2131" }, + "Ѓ": { "codepoints": [1027], "characters": "\u0403" }, + ">": { "codepoints": [62], "characters": "\u003E" }, + ">": { "codepoints": [62], "characters": "\u003E" }, + "Γ": { "codepoints": [915], "characters": "\u0393" }, + "Ϝ": { "codepoints": [988], "characters": "\u03DC" }, + "Ğ": { "codepoints": [286], "characters": "\u011E" }, + "Ģ": { "codepoints": [290], "characters": "\u0122" }, + "Ĝ": { "codepoints": [284], "characters": "\u011C" }, + "Г": { "codepoints": [1043], "characters": "\u0413" }, + "Ġ": { "codepoints": [288], "characters": "\u0120" }, + "𝔊": { "codepoints": [120074], "characters": "\uD835\uDD0A" }, + "⋙": { "codepoints": [8921], "characters": "\u22D9" }, + "𝔾": { "codepoints": [120126], "characters": "\uD835\uDD3E" }, + "≥": { "codepoints": [8805], "characters": "\u2265" }, + "⋛": { "codepoints": [8923], "characters": "\u22DB" }, + "≧": { "codepoints": [8807], "characters": "\u2267" }, + "⪢": { "codepoints": [10914], "characters": "\u2AA2" }, + "≷": { "codepoints": [8823], "characters": "\u2277" }, + "⩾": { "codepoints": [10878], "characters": "\u2A7E" }, + "≳": { "codepoints": [8819], "characters": "\u2273" }, + "𝒢": { "codepoints": [119970], "characters": "\uD835\uDCA2" }, + "≫": { "codepoints": [8811], "characters": "\u226B" }, + "Ъ": { "codepoints": [1066], "characters": "\u042A" }, + "ˇ": { "codepoints": [711], "characters": "\u02C7" }, + "^": { "codepoints": [94], "characters": "\u005E" }, + "Ĥ": { "codepoints": [292], "characters": "\u0124" }, + "ℌ": { "codepoints": [8460], "characters": "\u210C" }, + "ℋ": { "codepoints": [8459], "characters": "\u210B" }, + "ℍ": { "codepoints": [8461], "characters": "\u210D" }, + "─": { "codepoints": [9472], "characters": "\u2500" }, + "ℋ": { "codepoints": [8459], "characters": "\u210B" }, + "Ħ": { "codepoints": [294], "characters": "\u0126" }, + "≎": { "codepoints": [8782], "characters": "\u224E" }, + "≏": { "codepoints": [8783], "characters": "\u224F" }, + "Е": { "codepoints": [1045], "characters": "\u0415" }, + "IJ": { "codepoints": [306], "characters": "\u0132" }, + "Ё": { "codepoints": [1025], "characters": "\u0401" }, + "Í": { "codepoints": [205], "characters": "\u00CD" }, + "Í": { "codepoints": [205], "characters": "\u00CD" }, + "Î": { "codepoints": [206], "characters": "\u00CE" }, + "Î": { "codepoints": [206], "characters": "\u00CE" }, + "И": { "codepoints": [1048], "characters": "\u0418" }, + "İ": { "codepoints": [304], "characters": "\u0130" }, + "ℑ": { "codepoints": [8465], "characters": "\u2111" }, + "Ì": { "codepoints": [204], "characters": "\u00CC" }, + "Ì": { "codepoints": [204], "characters": "\u00CC" }, + "ℑ": { "codepoints": [8465], "characters": "\u2111" }, + "Ī": { "codepoints": [298], "characters": "\u012A" }, + "ⅈ": { "codepoints": [8520], "characters": "\u2148" }, + "⇒": { "codepoints": [8658], "characters": "\u21D2" }, + "∬": { "codepoints": [8748], "characters": "\u222C" }, + "∫": { "codepoints": [8747], "characters": "\u222B" }, + "⋂": { "codepoints": [8898], "characters": "\u22C2" }, + "⁣": { "codepoints": [8291], "characters": "\u2063" }, + "⁢": { "codepoints": [8290], "characters": "\u2062" }, + "Į": { "codepoints": [302], "characters": "\u012E" }, + "𝕀": { "codepoints": [120128], "characters": "\uD835\uDD40" }, + "Ι": { "codepoints": [921], "characters": "\u0399" }, + "ℐ": { "codepoints": [8464], "characters": "\u2110" }, + "Ĩ": { "codepoints": [296], "characters": "\u0128" }, + "І": { "codepoints": [1030], "characters": "\u0406" }, + "Ï": { "codepoints": [207], "characters": "\u00CF" }, + "Ï": { "codepoints": [207], "characters": "\u00CF" }, + "Ĵ": { "codepoints": [308], "characters": "\u0134" }, + "Й": { "codepoints": [1049], "characters": "\u0419" }, + "𝔍": { "codepoints": [120077], "characters": "\uD835\uDD0D" }, + "𝕁": { "codepoints": [120129], "characters": "\uD835\uDD41" }, + "𝒥": { "codepoints": [119973], "characters": "\uD835\uDCA5" }, + "Ј": { "codepoints": [1032], "characters": "\u0408" }, + "Є": { "codepoints": [1028], "characters": "\u0404" }, + "Х": { "codepoints": [1061], "characters": "\u0425" }, + "Ќ": { "codepoints": [1036], "characters": "\u040C" }, + "Κ": { "codepoints": [922], "characters": "\u039A" }, + "Ķ": { "codepoints": [310], "characters": "\u0136" }, + "К": { "codepoints": [1050], "characters": "\u041A" }, + "𝔎": { "codepoints": [120078], "characters": "\uD835\uDD0E" }, + "𝕂": { "codepoints": [120130], "characters": "\uD835\uDD42" }, + "𝒦": { "codepoints": [119974], "characters": "\uD835\uDCA6" }, + "Љ": { "codepoints": [1033], "characters": "\u0409" }, + "<": { "codepoints": [60], "characters": "\u003C" }, + "<": { "codepoints": [60], "characters": "\u003C" }, + "Ĺ": { "codepoints": [313], "characters": "\u0139" }, + "Λ": { "codepoints": [923], "characters": "\u039B" }, + "⟪": { "codepoints": [10218], "characters": "\u27EA" }, + "ℒ": { "codepoints": [8466], "characters": "\u2112" }, + "↞": { "codepoints": [8606], "characters": "\u219E" }, + "Ľ": { "codepoints": [317], "characters": "\u013D" }, + "Ļ": { "codepoints": [315], "characters": "\u013B" }, + "Л": { "codepoints": [1051], "characters": "\u041B" }, + "⟨": { "codepoints": [10216], "characters": "\u27E8" }, + "←": { "codepoints": [8592], "characters": "\u2190" }, + "⇤": { "codepoints": [8676], "characters": "\u21E4" }, + "⇆": { "codepoints": [8646], "characters": "\u21C6" }, + "⌈": { "codepoints": [8968], "characters": "\u2308" }, + "⟦": { "codepoints": [10214], "characters": "\u27E6" }, + "⥡": { "codepoints": [10593], "characters": "\u2961" }, + "⇃": { "codepoints": [8643], "characters": "\u21C3" }, + "⥙": { "codepoints": [10585], "characters": "\u2959" }, + "⌊": { "codepoints": [8970], "characters": "\u230A" }, + "↔": { "codepoints": [8596], "characters": "\u2194" }, + "⥎": { "codepoints": [10574], "characters": "\u294E" }, + "⊣": { "codepoints": [8867], "characters": "\u22A3" }, + "↤": { "codepoints": [8612], "characters": "\u21A4" }, + "⥚": { "codepoints": [10586], "characters": "\u295A" }, + "⊲": { "codepoints": [8882], "characters": "\u22B2" }, + "⧏": { "codepoints": [10703], "characters": "\u29CF" }, + "⊴": { "codepoints": [8884], "characters": "\u22B4" }, + "⥑": { "codepoints": [10577], "characters": "\u2951" }, + "⥠": { "codepoints": [10592], "characters": "\u2960" }, + "↿": { "codepoints": [8639], "characters": "\u21BF" }, + "⥘": { "codepoints": [10584], "characters": "\u2958" }, + "↼": { "codepoints": [8636], "characters": "\u21BC" }, + "⥒": { "codepoints": [10578], "characters": "\u2952" }, + "⇐": { "codepoints": [8656], "characters": "\u21D0" }, + "⇔": { "codepoints": [8660], "characters": "\u21D4" }, + "⋚": { "codepoints": [8922], "characters": "\u22DA" }, + "≦": { "codepoints": [8806], "characters": "\u2266" }, + "≶": { "codepoints": [8822], "characters": "\u2276" }, + "⪡": { "codepoints": [10913], "characters": "\u2AA1" }, + "⩽": { "codepoints": [10877], "characters": "\u2A7D" }, + "≲": { "codepoints": [8818], "characters": "\u2272" }, + "𝔏": { "codepoints": [120079], "characters": "\uD835\uDD0F" }, + "⋘": { "codepoints": [8920], "characters": "\u22D8" }, + "⇚": { "codepoints": [8666], "characters": "\u21DA" }, + "Ŀ": { "codepoints": [319], "characters": "\u013F" }, + "⟵": { "codepoints": [10229], "characters": "\u27F5" }, + "⟷": { "codepoints": [10231], "characters": "\u27F7" }, + "⟶": { "codepoints": [10230], "characters": "\u27F6" }, + "⟸": { "codepoints": [10232], "characters": "\u27F8" }, + "⟺": { "codepoints": [10234], "characters": "\u27FA" }, + "⟹": { "codepoints": [10233], "characters": "\u27F9" }, + "𝕃": { "codepoints": [120131], "characters": "\uD835\uDD43" }, + "↙": { "codepoints": [8601], "characters": "\u2199" }, + "↘": { "codepoints": [8600], "characters": "\u2198" }, + "ℒ": { "codepoints": [8466], "characters": "\u2112" }, + "↰": { "codepoints": [8624], "characters": "\u21B0" }, + "Ł": { "codepoints": [321], "characters": "\u0141" }, + "≪": { "codepoints": [8810], "characters": "\u226A" }, + "⤅": { "codepoints": [10501], "characters": "\u2905" }, + "М": { "codepoints": [1052], "characters": "\u041C" }, + " ": { "codepoints": [8287], "characters": "\u205F" }, + "ℳ": { "codepoints": [8499], "characters": "\u2133" }, + "𝔐": { "codepoints": [120080], "characters": "\uD835\uDD10" }, + "∓": { "codepoints": [8723], "characters": "\u2213" }, + "𝕄": { "codepoints": [120132], "characters": "\uD835\uDD44" }, + "ℳ": { "codepoints": [8499], "characters": "\u2133" }, + "Μ": { "codepoints": [924], "characters": "\u039C" }, + "Њ": { "codepoints": [1034], "characters": "\u040A" }, + "Ń": { "codepoints": [323], "characters": "\u0143" }, + "Ň": { "codepoints": [327], "characters": "\u0147" }, + "Ņ": { "codepoints": [325], "characters": "\u0145" }, + "Н": { "codepoints": [1053], "characters": "\u041D" }, + "​": { "codepoints": [8203], "characters": "\u200B" }, + "​": { "codepoints": [8203], "characters": "\u200B" }, + "​": { "codepoints": [8203], "characters": "\u200B" }, + "​": { "codepoints": [8203], "characters": "\u200B" }, + "≫": { "codepoints": [8811], "characters": "\u226B" }, + "≪": { "codepoints": [8810], "characters": "\u226A" }, + " ": { "codepoints": [10], "characters": "\u000A" }, + "𝔑": { "codepoints": [120081], "characters": "\uD835\uDD11" }, + "⁠": { "codepoints": [8288], "characters": "\u2060" }, + " ": { "codepoints": [160], "characters": "\u00A0" }, + "ℕ": { "codepoints": [8469], "characters": "\u2115" }, + "⫬": { "codepoints": [10988], "characters": "\u2AEC" }, + "≢": { "codepoints": [8802], "characters": "\u2262" }, + "≭": { "codepoints": [8813], "characters": "\u226D" }, + "∦": { "codepoints": [8742], "characters": "\u2226" }, + "∉": { "codepoints": [8713], "characters": "\u2209" }, + "≠": { "codepoints": [8800], "characters": "\u2260" }, + "≂̸": { "codepoints": [8770, 824], "characters": "\u2242\u0338" }, + "∄": { "codepoints": [8708], "characters": "\u2204" }, + "≯": { "codepoints": [8815], "characters": "\u226F" }, + "≱": { "codepoints": [8817], "characters": "\u2271" }, + "≧̸": { "codepoints": [8807, 824], "characters": "\u2267\u0338" }, + "≫̸": { "codepoints": [8811, 824], "characters": "\u226B\u0338" }, + "≹": { "codepoints": [8825], "characters": "\u2279" }, + "⩾̸": { "codepoints": [10878, 824], "characters": "\u2A7E\u0338" }, + "≵": { "codepoints": [8821], "characters": "\u2275" }, + "≎̸": { "codepoints": [8782, 824], "characters": "\u224E\u0338" }, + "≏̸": { "codepoints": [8783, 824], "characters": "\u224F\u0338" }, + "⋪": { "codepoints": [8938], "characters": "\u22EA" }, + "⧏̸": { "codepoints": [10703, 824], "characters": "\u29CF\u0338" }, + "⋬": { "codepoints": [8940], "characters": "\u22EC" }, + "≮": { "codepoints": [8814], "characters": "\u226E" }, + "≰": { "codepoints": [8816], "characters": "\u2270" }, + "≸": { "codepoints": [8824], "characters": "\u2278" }, + "≪̸": { "codepoints": [8810, 824], "characters": "\u226A\u0338" }, + "⩽̸": { "codepoints": [10877, 824], "characters": "\u2A7D\u0338" }, + "≴": { "codepoints": [8820], "characters": "\u2274" }, + "⪢̸": { "codepoints": [10914, 824], "characters": "\u2AA2\u0338" }, + "⪡̸": { "codepoints": [10913, 824], "characters": "\u2AA1\u0338" }, + "⊀": { "codepoints": [8832], "characters": "\u2280" }, + "⪯̸": { "codepoints": [10927, 824], "characters": "\u2AAF\u0338" }, + "⋠": { "codepoints": [8928], "characters": "\u22E0" }, + "∌": { "codepoints": [8716], "characters": "\u220C" }, + "⋫": { "codepoints": [8939], "characters": "\u22EB" }, + "⧐̸": { "codepoints": [10704, 824], "characters": "\u29D0\u0338" }, + "⋭": { "codepoints": [8941], "characters": "\u22ED" }, + "⊏̸": { "codepoints": [8847, 824], "characters": "\u228F\u0338" }, + "⋢": { "codepoints": [8930], "characters": "\u22E2" }, + "⊐̸": { "codepoints": [8848, 824], "characters": "\u2290\u0338" }, + "⋣": { "codepoints": [8931], "characters": "\u22E3" }, + "⊂⃒": { "codepoints": [8834, 8402], "characters": "\u2282\u20D2" }, + "⊈": { "codepoints": [8840], "characters": "\u2288" }, + "⊁": { "codepoints": [8833], "characters": "\u2281" }, + "⪰̸": { "codepoints": [10928, 824], "characters": "\u2AB0\u0338" }, + "⋡": { "codepoints": [8929], "characters": "\u22E1" }, + "≿̸": { "codepoints": [8831, 824], "characters": "\u227F\u0338" }, + "⊃⃒": { "codepoints": [8835, 8402], "characters": "\u2283\u20D2" }, + "⊉": { "codepoints": [8841], "characters": "\u2289" }, + "≁": { "codepoints": [8769], "characters": "\u2241" }, + "≄": { "codepoints": [8772], "characters": "\u2244" }, + "≇": { "codepoints": [8775], "characters": "\u2247" }, + "≉": { "codepoints": [8777], "characters": "\u2249" }, + "∤": { "codepoints": [8740], "characters": "\u2224" }, + "𝒩": { "codepoints": [119977], "characters": "\uD835\uDCA9" }, + "Ñ": { "codepoints": [209], "characters": "\u00D1" }, + "Ñ": { "codepoints": [209], "characters": "\u00D1" }, + "Ν": { "codepoints": [925], "characters": "\u039D" }, + "Œ": { "codepoints": [338], "characters": "\u0152" }, + "Ó": { "codepoints": [211], "characters": "\u00D3" }, + "Ó": { "codepoints": [211], "characters": "\u00D3" }, + "Ô": { "codepoints": [212], "characters": "\u00D4" }, + "Ô": { "codepoints": [212], "characters": "\u00D4" }, + "О": { "codepoints": [1054], "characters": "\u041E" }, + "Ő": { "codepoints": [336], "characters": "\u0150" }, + "𝔒": { "codepoints": [120082], "characters": "\uD835\uDD12" }, + "Ò": { "codepoints": [210], "characters": "\u00D2" }, + "Ò": { "codepoints": [210], "characters": "\u00D2" }, + "Ō": { "codepoints": [332], "characters": "\u014C" }, + "Ω": { "codepoints": [937], "characters": "\u03A9" }, + "Ο": { "codepoints": [927], "characters": "\u039F" }, + "𝕆": { "codepoints": [120134], "characters": "\uD835\uDD46" }, + "“": { "codepoints": [8220], "characters": "\u201C" }, + "‘": { "codepoints": [8216], "characters": "\u2018" }, + "⩔": { "codepoints": [10836], "characters": "\u2A54" }, + "𝒪": { "codepoints": [119978], "characters": "\uD835\uDCAA" }, + "Ø": { "codepoints": [216], "characters": "\u00D8" }, + "Ø": { "codepoints": [216], "characters": "\u00D8" }, + "Õ": { "codepoints": [213], "characters": "\u00D5" }, + "Õ": { "codepoints": [213], "characters": "\u00D5" }, + "⨷": { "codepoints": [10807], "characters": "\u2A37" }, + "Ö": { "codepoints": [214], "characters": "\u00D6" }, + "Ö": { "codepoints": [214], "characters": "\u00D6" }, + "‾": { "codepoints": [8254], "characters": "\u203E" }, + "⏞": { "codepoints": [9182], "characters": "\u23DE" }, + "⎴": { "codepoints": [9140], "characters": "\u23B4" }, + "⏜": { "codepoints": [9180], "characters": "\u23DC" }, + "∂": { "codepoints": [8706], "characters": "\u2202" }, + "П": { "codepoints": [1055], "characters": "\u041F" }, + "𝔓": { "codepoints": [120083], "characters": "\uD835\uDD13" }, + "Φ": { "codepoints": [934], "characters": "\u03A6" }, + "Π": { "codepoints": [928], "characters": "\u03A0" }, + "±": { "codepoints": [177], "characters": "\u00B1" }, + "ℌ": { "codepoints": [8460], "characters": "\u210C" }, + "ℙ": { "codepoints": [8473], "characters": "\u2119" }, + "⪻": { "codepoints": [10939], "characters": "\u2ABB" }, + "≺": { "codepoints": [8826], "characters": "\u227A" }, + "⪯": { "codepoints": [10927], "characters": "\u2AAF" }, + "≼": { "codepoints": [8828], "characters": "\u227C" }, + "≾": { "codepoints": [8830], "characters": "\u227E" }, + "″": { "codepoints": [8243], "characters": "\u2033" }, + "∏": { "codepoints": [8719], "characters": "\u220F" }, + "∷": { "codepoints": [8759], "characters": "\u2237" }, + "∝": { "codepoints": [8733], "characters": "\u221D" }, + "𝒫": { "codepoints": [119979], "characters": "\uD835\uDCAB" }, + "Ψ": { "codepoints": [936], "characters": "\u03A8" }, + """: { "codepoints": [34], "characters": "\u0022" }, + """: { "codepoints": [34], "characters": "\u0022" }, + "𝔔": { "codepoints": [120084], "characters": "\uD835\uDD14" }, + "ℚ": { "codepoints": [8474], "characters": "\u211A" }, + "𝒬": { "codepoints": [119980], "characters": "\uD835\uDCAC" }, + "⤐": { "codepoints": [10512], "characters": "\u2910" }, + "®": { "codepoints": [174], "characters": "\u00AE" }, + "®": { "codepoints": [174], "characters": "\u00AE" }, + "Ŕ": { "codepoints": [340], "characters": "\u0154" }, + "⟫": { "codepoints": [10219], "characters": "\u27EB" }, + "↠": { "codepoints": [8608], "characters": "\u21A0" }, + "⤖": { "codepoints": [10518], "characters": "\u2916" }, + "Ř": { "codepoints": [344], "characters": "\u0158" }, + "Ŗ": { "codepoints": [342], "characters": "\u0156" }, + "Р": { "codepoints": [1056], "characters": "\u0420" }, + "ℜ": { "codepoints": [8476], "characters": "\u211C" }, + "∋": { "codepoints": [8715], "characters": "\u220B" }, + "⇋": { "codepoints": [8651], "characters": "\u21CB" }, + "⥯": { "codepoints": [10607], "characters": "\u296F" }, + "ℜ": { "codepoints": [8476], "characters": "\u211C" }, + "Ρ": { "codepoints": [929], "characters": "\u03A1" }, + "⟩": { "codepoints": [10217], "characters": "\u27E9" }, + "→": { "codepoints": [8594], "characters": "\u2192" }, + "⇥": { "codepoints": [8677], "characters": "\u21E5" }, + "⇄": { "codepoints": [8644], "characters": "\u21C4" }, + "⌉": { "codepoints": [8969], "characters": "\u2309" }, + "⟧": { "codepoints": [10215], "characters": "\u27E7" }, + "⥝": { "codepoints": [10589], "characters": "\u295D" }, + "⇂": { "codepoints": [8642], "characters": "\u21C2" }, + "⥕": { "codepoints": [10581], "characters": "\u2955" }, + "⌋": { "codepoints": [8971], "characters": "\u230B" }, + "⊢": { "codepoints": [8866], "characters": "\u22A2" }, + "↦": { "codepoints": [8614], "characters": "\u21A6" }, + "⥛": { "codepoints": [10587], "characters": "\u295B" }, + "⊳": { "codepoints": [8883], "characters": "\u22B3" }, + "⧐": { "codepoints": [10704], "characters": "\u29D0" }, + "⊵": { "codepoints": [8885], "characters": "\u22B5" }, + "⥏": { "codepoints": [10575], "characters": "\u294F" }, + "⥜": { "codepoints": [10588], "characters": "\u295C" }, + "↾": { "codepoints": [8638], "characters": "\u21BE" }, + "⥔": { "codepoints": [10580], "characters": "\u2954" }, + "⇀": { "codepoints": [8640], "characters": "\u21C0" }, + "⥓": { "codepoints": [10579], "characters": "\u2953" }, + "⇒": { "codepoints": [8658], "characters": "\u21D2" }, + "ℝ": { "codepoints": [8477], "characters": "\u211D" }, + "⥰": { "codepoints": [10608], "characters": "\u2970" }, + "⇛": { "codepoints": [8667], "characters": "\u21DB" }, + "ℛ": { "codepoints": [8475], "characters": "\u211B" }, + "↱": { "codepoints": [8625], "characters": "\u21B1" }, + "⧴": { "codepoints": [10740], "characters": "\u29F4" }, + "Щ": { "codepoints": [1065], "characters": "\u0429" }, + "Ш": { "codepoints": [1064], "characters": "\u0428" }, + "Ь": { "codepoints": [1068], "characters": "\u042C" }, + "Ś": { "codepoints": [346], "characters": "\u015A" }, + "⪼": { "codepoints": [10940], "characters": "\u2ABC" }, + "Š": { "codepoints": [352], "characters": "\u0160" }, + "Ş": { "codepoints": [350], "characters": "\u015E" }, + "Ŝ": { "codepoints": [348], "characters": "\u015C" }, + "С": { "codepoints": [1057], "characters": "\u0421" }, + "𝔖": { "codepoints": [120086], "characters": "\uD835\uDD16" }, + "↓": { "codepoints": [8595], "characters": "\u2193" }, + "←": { "codepoints": [8592], "characters": "\u2190" }, + "→": { "codepoints": [8594], "characters": "\u2192" }, + "↑": { "codepoints": [8593], "characters": "\u2191" }, + "Σ": { "codepoints": [931], "characters": "\u03A3" }, + "∘": { "codepoints": [8728], "characters": "\u2218" }, + "𝕊": { "codepoints": [120138], "characters": "\uD835\uDD4A" }, + "√": { "codepoints": [8730], "characters": "\u221A" }, + "□": { "codepoints": [9633], "characters": "\u25A1" }, + "⊓": { "codepoints": [8851], "characters": "\u2293" }, + "⊏": { "codepoints": [8847], "characters": "\u228F" }, + "⊑": { "codepoints": [8849], "characters": "\u2291" }, + "⊐": { "codepoints": [8848], "characters": "\u2290" }, + "⊒": { "codepoints": [8850], "characters": "\u2292" }, + "⊔": { "codepoints": [8852], "characters": "\u2294" }, + "𝒮": { "codepoints": [119982], "characters": "\uD835\uDCAE" }, + "⋆": { "codepoints": [8902], "characters": "\u22C6" }, + "⋐": { "codepoints": [8912], "characters": "\u22D0" }, + "⋐": { "codepoints": [8912], "characters": "\u22D0" }, + "⊆": { "codepoints": [8838], "characters": "\u2286" }, + "≻": { "codepoints": [8827], "characters": "\u227B" }, + "⪰": { "codepoints": [10928], "characters": "\u2AB0" }, + "≽": { "codepoints": [8829], "characters": "\u227D" }, + "≿": { "codepoints": [8831], "characters": "\u227F" }, + "∋": { "codepoints": [8715], "characters": "\u220B" }, + "∑": { "codepoints": [8721], "characters": "\u2211" }, + "⋑": { "codepoints": [8913], "characters": "\u22D1" }, + "⊃": { "codepoints": [8835], "characters": "\u2283" }, + "⊇": { "codepoints": [8839], "characters": "\u2287" }, + "⋑": { "codepoints": [8913], "characters": "\u22D1" }, + "Þ": { "codepoints": [222], "characters": "\u00DE" }, + "Þ": { "codepoints": [222], "characters": "\u00DE" }, + "™": { "codepoints": [8482], "characters": "\u2122" }, + "Ћ": { "codepoints": [1035], "characters": "\u040B" }, + "Ц": { "codepoints": [1062], "characters": "\u0426" }, + " ": { "codepoints": [9], "characters": "\u0009" }, + "Τ": { "codepoints": [932], "characters": "\u03A4" }, + "Ť": { "codepoints": [356], "characters": "\u0164" }, + "Ţ": { "codepoints": [354], "characters": "\u0162" }, + "Т": { "codepoints": [1058], "characters": "\u0422" }, + "𝔗": { "codepoints": [120087], "characters": "\uD835\uDD17" }, + "∴": { "codepoints": [8756], "characters": "\u2234" }, + "Θ": { "codepoints": [920], "characters": "\u0398" }, + "  ": { "codepoints": [8287, 8202], "characters": "\u205F\u200A" }, + " ": { "codepoints": [8201], "characters": "\u2009" }, + "∼": { "codepoints": [8764], "characters": "\u223C" }, + "≃": { "codepoints": [8771], "characters": "\u2243" }, + "≅": { "codepoints": [8773], "characters": "\u2245" }, + "≈": { "codepoints": [8776], "characters": "\u2248" }, + "𝕋": { "codepoints": [120139], "characters": "\uD835\uDD4B" }, + "⃛": { "codepoints": [8411], "characters": "\u20DB" }, + "𝒯": { "codepoints": [119983], "characters": "\uD835\uDCAF" }, + "Ŧ": { "codepoints": [358], "characters": "\u0166" }, + "Ú": { "codepoints": [218], "characters": "\u00DA" }, + "Ú": { "codepoints": [218], "characters": "\u00DA" }, + "↟": { "codepoints": [8607], "characters": "\u219F" }, + "⥉": { "codepoints": [10569], "characters": "\u2949" }, + "Ў": { "codepoints": [1038], "characters": "\u040E" }, + "Ŭ": { "codepoints": [364], "characters": "\u016C" }, + "Û": { "codepoints": [219], "characters": "\u00DB" }, + "Û": { "codepoints": [219], "characters": "\u00DB" }, + "У": { "codepoints": [1059], "characters": "\u0423" }, + "Ű": { "codepoints": [368], "characters": "\u0170" }, + "𝔘": { "codepoints": [120088], "characters": "\uD835\uDD18" }, + "Ù": { "codepoints": [217], "characters": "\u00D9" }, + "Ù": { "codepoints": [217], "characters": "\u00D9" }, + "Ū": { "codepoints": [362], "characters": "\u016A" }, + "_": { "codepoints": [95], "characters": "\u005F" }, + "⏟": { "codepoints": [9183], "characters": "\u23DF" }, + "⎵": { "codepoints": [9141], "characters": "\u23B5" }, + "⏝": { "codepoints": [9181], "characters": "\u23DD" }, + "⋃": { "codepoints": [8899], "characters": "\u22C3" }, + "⊎": { "codepoints": [8846], "characters": "\u228E" }, + "Ų": { "codepoints": [370], "characters": "\u0172" }, + "𝕌": { "codepoints": [120140], "characters": "\uD835\uDD4C" }, + "↑": { "codepoints": [8593], "characters": "\u2191" }, + "⤒": { "codepoints": [10514], "characters": "\u2912" }, + "⇅": { "codepoints": [8645], "characters": "\u21C5" }, + "↕": { "codepoints": [8597], "characters": "\u2195" }, + "⥮": { "codepoints": [10606], "characters": "\u296E" }, + "⊥": { "codepoints": [8869], "characters": "\u22A5" }, + "↥": { "codepoints": [8613], "characters": "\u21A5" }, + "⇑": { "codepoints": [8657], "characters": "\u21D1" }, + "⇕": { "codepoints": [8661], "characters": "\u21D5" }, + "↖": { "codepoints": [8598], "characters": "\u2196" }, + "↗": { "codepoints": [8599], "characters": "\u2197" }, + "ϒ": { "codepoints": [978], "characters": "\u03D2" }, + "Υ": { "codepoints": [933], "characters": "\u03A5" }, + "Ů": { "codepoints": [366], "characters": "\u016E" }, + "𝒰": { "codepoints": [119984], "characters": "\uD835\uDCB0" }, + "Ũ": { "codepoints": [360], "characters": "\u0168" }, + "Ü": { "codepoints": [220], "characters": "\u00DC" }, + "Ü": { "codepoints": [220], "characters": "\u00DC" }, + "⊫": { "codepoints": [8875], "characters": "\u22AB" }, + "⫫": { "codepoints": [10987], "characters": "\u2AEB" }, + "В": { "codepoints": [1042], "characters": "\u0412" }, + "⊩": { "codepoints": [8873], "characters": "\u22A9" }, + "⫦": { "codepoints": [10982], "characters": "\u2AE6" }, + "⋁": { "codepoints": [8897], "characters": "\u22C1" }, + "‖": { "codepoints": [8214], "characters": "\u2016" }, + "‖": { "codepoints": [8214], "characters": "\u2016" }, + "∣": { "codepoints": [8739], "characters": "\u2223" }, + "|": { "codepoints": [124], "characters": "\u007C" }, + "❘": { "codepoints": [10072], "characters": "\u2758" }, + "≀": { "codepoints": [8768], "characters": "\u2240" }, + " ": { "codepoints": [8202], "characters": "\u200A" }, + "𝔙": { "codepoints": [120089], "characters": "\uD835\uDD19" }, + "𝕍": { "codepoints": [120141], "characters": "\uD835\uDD4D" }, + "𝒱": { "codepoints": [119985], "characters": "\uD835\uDCB1" }, + "⊪": { "codepoints": [8874], "characters": "\u22AA" }, + "Ŵ": { "codepoints": [372], "characters": "\u0174" }, + "⋀": { "codepoints": [8896], "characters": "\u22C0" }, + "𝔚": { "codepoints": [120090], "characters": "\uD835\uDD1A" }, + "𝕎": { "codepoints": [120142], "characters": "\uD835\uDD4E" }, + "𝒲": { "codepoints": [119986], "characters": "\uD835\uDCB2" }, + "𝔛": { "codepoints": [120091], "characters": "\uD835\uDD1B" }, + "Ξ": { "codepoints": [926], "characters": "\u039E" }, + "𝕏": { "codepoints": [120143], "characters": "\uD835\uDD4F" }, + "𝒳": { "codepoints": [119987], "characters": "\uD835\uDCB3" }, + "Я": { "codepoints": [1071], "characters": "\u042F" }, + "Ї": { "codepoints": [1031], "characters": "\u0407" }, + "Ю": { "codepoints": [1070], "characters": "\u042E" }, + "Ý": { "codepoints": [221], "characters": "\u00DD" }, + "Ý": { "codepoints": [221], "characters": "\u00DD" }, + "Ŷ": { "codepoints": [374], "characters": "\u0176" }, + "Ы": { "codepoints": [1067], "characters": "\u042B" }, + "𝔜": { "codepoints": [120092], "characters": "\uD835\uDD1C" }, + "𝕐": { "codepoints": [120144], "characters": "\uD835\uDD50" }, + "𝒴": { "codepoints": [119988], "characters": "\uD835\uDCB4" }, + "Ÿ": { "codepoints": [376], "characters": "\u0178" }, + "Ж": { "codepoints": [1046], "characters": "\u0416" }, + "Ź": { "codepoints": [377], "characters": "\u0179" }, + "Ž": { "codepoints": [381], "characters": "\u017D" }, + "З": { "codepoints": [1047], "characters": "\u0417" }, + "Ż": { "codepoints": [379], "characters": "\u017B" }, + "​": { "codepoints": [8203], "characters": "\u200B" }, + "Ζ": { "codepoints": [918], "characters": "\u0396" }, + "ℨ": { "codepoints": [8488], "characters": "\u2128" }, + "ℤ": { "codepoints": [8484], "characters": "\u2124" }, + "𝒵": { "codepoints": [119989], "characters": "\uD835\uDCB5" }, + "á": { "codepoints": [225], "characters": "\u00E1" }, + "á": { "codepoints": [225], "characters": "\u00E1" }, + "ă": { "codepoints": [259], "characters": "\u0103" }, + "∾": { "codepoints": [8766], "characters": "\u223E" }, + "∾̳": { "codepoints": [8766, 819], "characters": "\u223E\u0333" }, + "∿": { "codepoints": [8767], "characters": "\u223F" }, + "â": { "codepoints": [226], "characters": "\u00E2" }, + "â": { "codepoints": [226], "characters": "\u00E2" }, + "´": { "codepoints": [180], "characters": "\u00B4" }, + "´": { "codepoints": [180], "characters": "\u00B4" }, + "а": { "codepoints": [1072], "characters": "\u0430" }, + "æ": { "codepoints": [230], "characters": "\u00E6" }, + "æ": { "codepoints": [230], "characters": "\u00E6" }, + "⁡": { "codepoints": [8289], "characters": "\u2061" }, + "𝔞": { "codepoints": [120094], "characters": "\uD835\uDD1E" }, + "à": { "codepoints": [224], "characters": "\u00E0" }, + "à": { "codepoints": [224], "characters": "\u00E0" }, + "ℵ": { "codepoints": [8501], "characters": "\u2135" }, + "ℵ": { "codepoints": [8501], "characters": "\u2135" }, + "α": { "codepoints": [945], "characters": "\u03B1" }, + "ā": { "codepoints": [257], "characters": "\u0101" }, + "⨿": { "codepoints": [10815], "characters": "\u2A3F" }, + "&": { "codepoints": [38], "characters": "\u0026" }, + "&": { "codepoints": [38], "characters": "\u0026" }, + "∧": { "codepoints": [8743], "characters": "\u2227" }, + "⩕": { "codepoints": [10837], "characters": "\u2A55" }, + "⩜": { "codepoints": [10844], "characters": "\u2A5C" }, + "⩘": { "codepoints": [10840], "characters": "\u2A58" }, + "⩚": { "codepoints": [10842], "characters": "\u2A5A" }, + "∠": { "codepoints": [8736], "characters": "\u2220" }, + "⦤": { "codepoints": [10660], "characters": "\u29A4" }, + "∠": { "codepoints": [8736], "characters": "\u2220" }, + "∡": { "codepoints": [8737], "characters": "\u2221" }, + "⦨": { "codepoints": [10664], "characters": "\u29A8" }, + "⦩": { "codepoints": [10665], "characters": "\u29A9" }, + "⦪": { "codepoints": [10666], "characters": "\u29AA" }, + "⦫": { "codepoints": [10667], "characters": "\u29AB" }, + "⦬": { "codepoints": [10668], "characters": "\u29AC" }, + "⦭": { "codepoints": [10669], "characters": "\u29AD" }, + "⦮": { "codepoints": [10670], "characters": "\u29AE" }, + "⦯": { "codepoints": [10671], "characters": "\u29AF" }, + "∟": { "codepoints": [8735], "characters": "\u221F" }, + "⊾": { "codepoints": [8894], "characters": "\u22BE" }, + "⦝": { "codepoints": [10653], "characters": "\u299D" }, + "∢": { "codepoints": [8738], "characters": "\u2222" }, + "Å": { "codepoints": [197], "characters": "\u00C5" }, + "⍼": { "codepoints": [9084], "characters": "\u237C" }, + "ą": { "codepoints": [261], "characters": "\u0105" }, + "𝕒": { "codepoints": [120146], "characters": "\uD835\uDD52" }, + "≈": { "codepoints": [8776], "characters": "\u2248" }, + "⩰": { "codepoints": [10864], "characters": "\u2A70" }, + "⩯": { "codepoints": [10863], "characters": "\u2A6F" }, + "≊": { "codepoints": [8778], "characters": "\u224A" }, + "≋": { "codepoints": [8779], "characters": "\u224B" }, + "'": { "codepoints": [39], "characters": "\u0027" }, + "≈": { "codepoints": [8776], "characters": "\u2248" }, + "≊": { "codepoints": [8778], "characters": "\u224A" }, + "å": { "codepoints": [229], "characters": "\u00E5" }, + "å": { "codepoints": [229], "characters": "\u00E5" }, + "𝒶": { "codepoints": [119990], "characters": "\uD835\uDCB6" }, + "*": { "codepoints": [42], "characters": "\u002A" }, + "≈": { "codepoints": [8776], "characters": "\u2248" }, + "≍": { "codepoints": [8781], "characters": "\u224D" }, + "ã": { "codepoints": [227], "characters": "\u00E3" }, + "ã": { "codepoints": [227], "characters": "\u00E3" }, + "ä": { "codepoints": [228], "characters": "\u00E4" }, + "ä": { "codepoints": [228], "characters": "\u00E4" }, + "∳": { "codepoints": [8755], "characters": "\u2233" }, + "⨑": { "codepoints": [10769], "characters": "\u2A11" }, + "⫭": { "codepoints": [10989], "characters": "\u2AED" }, + "≌": { "codepoints": [8780], "characters": "\u224C" }, + "϶": { "codepoints": [1014], "characters": "\u03F6" }, + "‵": { "codepoints": [8245], "characters": "\u2035" }, + "∽": { "codepoints": [8765], "characters": "\u223D" }, + "⋍": { "codepoints": [8909], "characters": "\u22CD" }, + "⊽": { "codepoints": [8893], "characters": "\u22BD" }, + "⌅": { "codepoints": [8965], "characters": "\u2305" }, + "⌅": { "codepoints": [8965], "characters": "\u2305" }, + "⎵": { "codepoints": [9141], "characters": "\u23B5" }, + "⎶": { "codepoints": [9142], "characters": "\u23B6" }, + "≌": { "codepoints": [8780], "characters": "\u224C" }, + "б": { "codepoints": [1073], "characters": "\u0431" }, + "„": { "codepoints": [8222], "characters": "\u201E" }, + "∵": { "codepoints": [8757], "characters": "\u2235" }, + "∵": { "codepoints": [8757], "characters": "\u2235" }, + "⦰": { "codepoints": [10672], "characters": "\u29B0" }, + "϶": { "codepoints": [1014], "characters": "\u03F6" }, + "ℬ": { "codepoints": [8492], "characters": "\u212C" }, + "β": { "codepoints": [946], "characters": "\u03B2" }, + "ℶ": { "codepoints": [8502], "characters": "\u2136" }, + "≬": { "codepoints": [8812], "characters": "\u226C" }, + "𝔟": { "codepoints": [120095], "characters": "\uD835\uDD1F" }, + "⋂": { "codepoints": [8898], "characters": "\u22C2" }, + "◯": { "codepoints": [9711], "characters": "\u25EF" }, + "⋃": { "codepoints": [8899], "characters": "\u22C3" }, + "⨀": { "codepoints": [10752], "characters": "\u2A00" }, + "⨁": { "codepoints": [10753], "characters": "\u2A01" }, + "⨂": { "codepoints": [10754], "characters": "\u2A02" }, + "⨆": { "codepoints": [10758], "characters": "\u2A06" }, + "★": { "codepoints": [9733], "characters": "\u2605" }, + "▽": { "codepoints": [9661], "characters": "\u25BD" }, + "△": { "codepoints": [9651], "characters": "\u25B3" }, + "⨄": { "codepoints": [10756], "characters": "\u2A04" }, + "⋁": { "codepoints": [8897], "characters": "\u22C1" }, + "⋀": { "codepoints": [8896], "characters": "\u22C0" }, + "⤍": { "codepoints": [10509], "characters": "\u290D" }, + "⧫": { "codepoints": [10731], "characters": "\u29EB" }, + "▪": { "codepoints": [9642], "characters": "\u25AA" }, + "▴": { "codepoints": [9652], "characters": "\u25B4" }, + "▾": { "codepoints": [9662], "characters": "\u25BE" }, + "◂": { "codepoints": [9666], "characters": "\u25C2" }, + "▸": { "codepoints": [9656], "characters": "\u25B8" }, + "␣": { "codepoints": [9251], "characters": "\u2423" }, + "▒": { "codepoints": [9618], "characters": "\u2592" }, + "░": { "codepoints": [9617], "characters": "\u2591" }, + "▓": { "codepoints": [9619], "characters": "\u2593" }, + "█": { "codepoints": [9608], "characters": "\u2588" }, + "=⃥": { "codepoints": [61, 8421], "characters": "\u003D\u20E5" }, + "≡⃥": { "codepoints": [8801, 8421], "characters": "\u2261\u20E5" }, + "⌐": { "codepoints": [8976], "characters": "\u2310" }, + "𝕓": { "codepoints": [120147], "characters": "\uD835\uDD53" }, + "⊥": { "codepoints": [8869], "characters": "\u22A5" }, + "⊥": { "codepoints": [8869], "characters": "\u22A5" }, + "⋈": { "codepoints": [8904], "characters": "\u22C8" }, + "╗": { "codepoints": [9559], "characters": "\u2557" }, + "╔": { "codepoints": [9556], "characters": "\u2554" }, + "╖": { "codepoints": [9558], "characters": "\u2556" }, + "╓": { "codepoints": [9555], "characters": "\u2553" }, + "═": { "codepoints": [9552], "characters": "\u2550" }, + "╦": { "codepoints": [9574], "characters": "\u2566" }, + "╩": { "codepoints": [9577], "characters": "\u2569" }, + "╤": { "codepoints": [9572], "characters": "\u2564" }, + "╧": { "codepoints": [9575], "characters": "\u2567" }, + "╝": { "codepoints": [9565], "characters": "\u255D" }, + "╚": { "codepoints": [9562], "characters": "\u255A" }, + "╜": { "codepoints": [9564], "characters": "\u255C" }, + "╙": { "codepoints": [9561], "characters": "\u2559" }, + "║": { "codepoints": [9553], "characters": "\u2551" }, + "╬": { "codepoints": [9580], "characters": "\u256C" }, + "╣": { "codepoints": [9571], "characters": "\u2563" }, + "╠": { "codepoints": [9568], "characters": "\u2560" }, + "╫": { "codepoints": [9579], "characters": "\u256B" }, + "╢": { "codepoints": [9570], "characters": "\u2562" }, + "╟": { "codepoints": [9567], "characters": "\u255F" }, + "⧉": { "codepoints": [10697], "characters": "\u29C9" }, + "╕": { "codepoints": [9557], "characters": "\u2555" }, + "╒": { "codepoints": [9554], "characters": "\u2552" }, + "┐": { "codepoints": [9488], "characters": "\u2510" }, + "┌": { "codepoints": [9484], "characters": "\u250C" }, + "─": { "codepoints": [9472], "characters": "\u2500" }, + "╥": { "codepoints": [9573], "characters": "\u2565" }, + "╨": { "codepoints": [9576], "characters": "\u2568" }, + "┬": { "codepoints": [9516], "characters": "\u252C" }, + "┴": { "codepoints": [9524], "characters": "\u2534" }, + "⊟": { "codepoints": [8863], "characters": "\u229F" }, + "⊞": { "codepoints": [8862], "characters": "\u229E" }, + "⊠": { "codepoints": [8864], "characters": "\u22A0" }, + "╛": { "codepoints": [9563], "characters": "\u255B" }, + "╘": { "codepoints": [9560], "characters": "\u2558" }, + "┘": { "codepoints": [9496], "characters": "\u2518" }, + "└": { "codepoints": [9492], "characters": "\u2514" }, + "│": { "codepoints": [9474], "characters": "\u2502" }, + "╪": { "codepoints": [9578], "characters": "\u256A" }, + "╡": { "codepoints": [9569], "characters": "\u2561" }, + "╞": { "codepoints": [9566], "characters": "\u255E" }, + "┼": { "codepoints": [9532], "characters": "\u253C" }, + "┤": { "codepoints": [9508], "characters": "\u2524" }, + "├": { "codepoints": [9500], "characters": "\u251C" }, + "‵": { "codepoints": [8245], "characters": "\u2035" }, + "˘": { "codepoints": [728], "characters": "\u02D8" }, + "¦": { "codepoints": [166], "characters": "\u00A6" }, + "¦": { "codepoints": [166], "characters": "\u00A6" }, + "𝒷": { "codepoints": [119991], "characters": "\uD835\uDCB7" }, + "⁏": { "codepoints": [8271], "characters": "\u204F" }, + "∽": { "codepoints": [8765], "characters": "\u223D" }, + "⋍": { "codepoints": [8909], "characters": "\u22CD" }, + "\": { "codepoints": [92], "characters": "\u005C" }, + "⧅": { "codepoints": [10693], "characters": "\u29C5" }, + "⟈": { "codepoints": [10184], "characters": "\u27C8" }, + "•": { "codepoints": [8226], "characters": "\u2022" }, + "•": { "codepoints": [8226], "characters": "\u2022" }, + "≎": { "codepoints": [8782], "characters": "\u224E" }, + "⪮": { "codepoints": [10926], "characters": "\u2AAE" }, + "≏": { "codepoints": [8783], "characters": "\u224F" }, + "≏": { "codepoints": [8783], "characters": "\u224F" }, + "ć": { "codepoints": [263], "characters": "\u0107" }, + "∩": { "codepoints": [8745], "characters": "\u2229" }, + "⩄": { "codepoints": [10820], "characters": "\u2A44" }, + "⩉": { "codepoints": [10825], "characters": "\u2A49" }, + "⩋": { "codepoints": [10827], "characters": "\u2A4B" }, + "⩇": { "codepoints": [10823], "characters": "\u2A47" }, + "⩀": { "codepoints": [10816], "characters": "\u2A40" }, + "∩︀": { "codepoints": [8745, 65024], "characters": "\u2229\uFE00" }, + "⁁": { "codepoints": [8257], "characters": "\u2041" }, + "ˇ": { "codepoints": [711], "characters": "\u02C7" }, + "⩍": { "codepoints": [10829], "characters": "\u2A4D" }, + "č": { "codepoints": [269], "characters": "\u010D" }, + "ç": { "codepoints": [231], "characters": "\u00E7" }, + "ç": { "codepoints": [231], "characters": "\u00E7" }, + "ĉ": { "codepoints": [265], "characters": "\u0109" }, + "⩌": { "codepoints": [10828], "characters": "\u2A4C" }, + "⩐": { "codepoints": [10832], "characters": "\u2A50" }, + "ċ": { "codepoints": [267], "characters": "\u010B" }, + "¸": { "codepoints": [184], "characters": "\u00B8" }, + "¸": { "codepoints": [184], "characters": "\u00B8" }, + "⦲": { "codepoints": [10674], "characters": "\u29B2" }, + "¢": { "codepoints": [162], "characters": "\u00A2" }, + "¢": { "codepoints": [162], "characters": "\u00A2" }, + "·": { "codepoints": [183], "characters": "\u00B7" }, + "𝔠": { "codepoints": [120096], "characters": "\uD835\uDD20" }, + "ч": { "codepoints": [1095], "characters": "\u0447" }, + "✓": { "codepoints": [10003], "characters": "\u2713" }, + "✓": { "codepoints": [10003], "characters": "\u2713" }, + "χ": { "codepoints": [967], "characters": "\u03C7" }, + "○": { "codepoints": [9675], "characters": "\u25CB" }, + "⧃": { "codepoints": [10691], "characters": "\u29C3" }, + "ˆ": { "codepoints": [710], "characters": "\u02C6" }, + "≗": { "codepoints": [8791], "characters": "\u2257" }, + "↺": { "codepoints": [8634], "characters": "\u21BA" }, + "↻": { "codepoints": [8635], "characters": "\u21BB" }, + "®": { "codepoints": [174], "characters": "\u00AE" }, + "Ⓢ": { "codepoints": [9416], "characters": "\u24C8" }, + "⊛": { "codepoints": [8859], "characters": "\u229B" }, + "⊚": { "codepoints": [8858], "characters": "\u229A" }, + "⊝": { "codepoints": [8861], "characters": "\u229D" }, + "≗": { "codepoints": [8791], "characters": "\u2257" }, + "⨐": { "codepoints": [10768], "characters": "\u2A10" }, + "⫯": { "codepoints": [10991], "characters": "\u2AEF" }, + "⧂": { "codepoints": [10690], "characters": "\u29C2" }, + "♣": { "codepoints": [9827], "characters": "\u2663" }, + "♣": { "codepoints": [9827], "characters": "\u2663" }, + ":": { "codepoints": [58], "characters": "\u003A" }, + "≔": { "codepoints": [8788], "characters": "\u2254" }, + "≔": { "codepoints": [8788], "characters": "\u2254" }, + ",": { "codepoints": [44], "characters": "\u002C" }, + "@": { "codepoints": [64], "characters": "\u0040" }, + "∁": { "codepoints": [8705], "characters": "\u2201" }, + "∘": { "codepoints": [8728], "characters": "\u2218" }, + "∁": { "codepoints": [8705], "characters": "\u2201" }, + "ℂ": { "codepoints": [8450], "characters": "\u2102" }, + "≅": { "codepoints": [8773], "characters": "\u2245" }, + "⩭": { "codepoints": [10861], "characters": "\u2A6D" }, + "∮": { "codepoints": [8750], "characters": "\u222E" }, + "𝕔": { "codepoints": [120148], "characters": "\uD835\uDD54" }, + "∐": { "codepoints": [8720], "characters": "\u2210" }, + "©": { "codepoints": [169], "characters": "\u00A9" }, + "©": { "codepoints": [169], "characters": "\u00A9" }, + "℗": { "codepoints": [8471], "characters": "\u2117" }, + "↵": { "codepoints": [8629], "characters": "\u21B5" }, + "✗": { "codepoints": [10007], "characters": "\u2717" }, + "𝒸": { "codepoints": [119992], "characters": "\uD835\uDCB8" }, + "⫏": { "codepoints": [10959], "characters": "\u2ACF" }, + "⫑": { "codepoints": [10961], "characters": "\u2AD1" }, + "⫐": { "codepoints": [10960], "characters": "\u2AD0" }, + "⫒": { "codepoints": [10962], "characters": "\u2AD2" }, + "⋯": { "codepoints": [8943], "characters": "\u22EF" }, + "⤸": { "codepoints": [10552], "characters": "\u2938" }, + "⤵": { "codepoints": [10549], "characters": "\u2935" }, + "⋞": { "codepoints": [8926], "characters": "\u22DE" }, + "⋟": { "codepoints": [8927], "characters": "\u22DF" }, + "↶": { "codepoints": [8630], "characters": "\u21B6" }, + "⤽": { "codepoints": [10557], "characters": "\u293D" }, + "∪": { "codepoints": [8746], "characters": "\u222A" }, + "⩈": { "codepoints": [10824], "characters": "\u2A48" }, + "⩆": { "codepoints": [10822], "characters": "\u2A46" }, + "⩊": { "codepoints": [10826], "characters": "\u2A4A" }, + "⊍": { "codepoints": [8845], "characters": "\u228D" }, + "⩅": { "codepoints": [10821], "characters": "\u2A45" }, + "∪︀": { "codepoints": [8746, 65024], "characters": "\u222A\uFE00" }, + "↷": { "codepoints": [8631], "characters": "\u21B7" }, + "⤼": { "codepoints": [10556], "characters": "\u293C" }, + "⋞": { "codepoints": [8926], "characters": "\u22DE" }, + "⋟": { "codepoints": [8927], "characters": "\u22DF" }, + "⋎": { "codepoints": [8910], "characters": "\u22CE" }, + "⋏": { "codepoints": [8911], "characters": "\u22CF" }, + "¤": { "codepoints": [164], "characters": "\u00A4" }, + "¤": { "codepoints": [164], "characters": "\u00A4" }, + "↶": { "codepoints": [8630], "characters": "\u21B6" }, + "↷": { "codepoints": [8631], "characters": "\u21B7" }, + "⋎": { "codepoints": [8910], "characters": "\u22CE" }, + "⋏": { "codepoints": [8911], "characters": "\u22CF" }, + "∲": { "codepoints": [8754], "characters": "\u2232" }, + "∱": { "codepoints": [8753], "characters": "\u2231" }, + "⌭": { "codepoints": [9005], "characters": "\u232D" }, + "⇓": { "codepoints": [8659], "characters": "\u21D3" }, + "⥥": { "codepoints": [10597], "characters": "\u2965" }, + "†": { "codepoints": [8224], "characters": "\u2020" }, + "ℸ": { "codepoints": [8504], "characters": "\u2138" }, + "↓": { "codepoints": [8595], "characters": "\u2193" }, + "‐": { "codepoints": [8208], "characters": "\u2010" }, + "⊣": { "codepoints": [8867], "characters": "\u22A3" }, + "⤏": { "codepoints": [10511], "characters": "\u290F" }, + "˝": { "codepoints": [733], "characters": "\u02DD" }, + "ď": { "codepoints": [271], "characters": "\u010F" }, + "д": { "codepoints": [1076], "characters": "\u0434" }, + "ⅆ": { "codepoints": [8518], "characters": "\u2146" }, + "‡": { "codepoints": [8225], "characters": "\u2021" }, + "⇊": { "codepoints": [8650], "characters": "\u21CA" }, + "⩷": { "codepoints": [10871], "characters": "\u2A77" }, + "°": { "codepoints": [176], "characters": "\u00B0" }, + "°": { "codepoints": [176], "characters": "\u00B0" }, + "δ": { "codepoints": [948], "characters": "\u03B4" }, + "⦱": { "codepoints": [10673], "characters": "\u29B1" }, + "⥿": { "codepoints": [10623], "characters": "\u297F" }, + "𝔡": { "codepoints": [120097], "characters": "\uD835\uDD21" }, + "⇃": { "codepoints": [8643], "characters": "\u21C3" }, + "⇂": { "codepoints": [8642], "characters": "\u21C2" }, + "⋄": { "codepoints": [8900], "characters": "\u22C4" }, + "⋄": { "codepoints": [8900], "characters": "\u22C4" }, + "♦": { "codepoints": [9830], "characters": "\u2666" }, + "♦": { "codepoints": [9830], "characters": "\u2666" }, + "¨": { "codepoints": [168], "characters": "\u00A8" }, + "ϝ": { "codepoints": [989], "characters": "\u03DD" }, + "⋲": { "codepoints": [8946], "characters": "\u22F2" }, + "÷": { "codepoints": [247], "characters": "\u00F7" }, + "÷": { "codepoints": [247], "characters": "\u00F7" }, + "÷": { "codepoints": [247], "characters": "\u00F7" }, + "⋇": { "codepoints": [8903], "characters": "\u22C7" }, + "⋇": { "codepoints": [8903], "characters": "\u22C7" }, + "ђ": { "codepoints": [1106], "characters": "\u0452" }, + "⌞": { "codepoints": [8990], "characters": "\u231E" }, + "⌍": { "codepoints": [8973], "characters": "\u230D" }, + "$": { "codepoints": [36], "characters": "\u0024" }, + "𝕕": { "codepoints": [120149], "characters": "\uD835\uDD55" }, + "˙": { "codepoints": [729], "characters": "\u02D9" }, + "≐": { "codepoints": [8784], "characters": "\u2250" }, + "≑": { "codepoints": [8785], "characters": "\u2251" }, + "∸": { "codepoints": [8760], "characters": "\u2238" }, + "∔": { "codepoints": [8724], "characters": "\u2214" }, + "⊡": { "codepoints": [8865], "characters": "\u22A1" }, + "⌆": { "codepoints": [8966], "characters": "\u2306" }, + "↓": { "codepoints": [8595], "characters": "\u2193" }, + "⇊": { "codepoints": [8650], "characters": "\u21CA" }, + "⇃": { "codepoints": [8643], "characters": "\u21C3" }, + "⇂": { "codepoints": [8642], "characters": "\u21C2" }, + "⤐": { "codepoints": [10512], "characters": "\u2910" }, + "⌟": { "codepoints": [8991], "characters": "\u231F" }, + "⌌": { "codepoints": [8972], "characters": "\u230C" }, + "𝒹": { "codepoints": [119993], "characters": "\uD835\uDCB9" }, + "ѕ": { "codepoints": [1109], "characters": "\u0455" }, + "⧶": { "codepoints": [10742], "characters": "\u29F6" }, + "đ": { "codepoints": [273], "characters": "\u0111" }, + "⋱": { "codepoints": [8945], "characters": "\u22F1" }, + "▿": { "codepoints": [9663], "characters": "\u25BF" }, + "▾": { "codepoints": [9662], "characters": "\u25BE" }, + "⇵": { "codepoints": [8693], "characters": "\u21F5" }, + "⥯": { "codepoints": [10607], "characters": "\u296F" }, + "⦦": { "codepoints": [10662], "characters": "\u29A6" }, + "џ": { "codepoints": [1119], "characters": "\u045F" }, + "⟿": { "codepoints": [10239], "characters": "\u27FF" }, + "⩷": { "codepoints": [10871], "characters": "\u2A77" }, + "≑": { "codepoints": [8785], "characters": "\u2251" }, + "é": { "codepoints": [233], "characters": "\u00E9" }, + "é": { "codepoints": [233], "characters": "\u00E9" }, + "⩮": { "codepoints": [10862], "characters": "\u2A6E" }, + "ě": { "codepoints": [283], "characters": "\u011B" }, + "≖": { "codepoints": [8790], "characters": "\u2256" }, + "ê": { "codepoints": [234], "characters": "\u00EA" }, + "ê": { "codepoints": [234], "characters": "\u00EA" }, + "≕": { "codepoints": [8789], "characters": "\u2255" }, + "э": { "codepoints": [1101], "characters": "\u044D" }, + "ė": { "codepoints": [279], "characters": "\u0117" }, + "ⅇ": { "codepoints": [8519], "characters": "\u2147" }, + "≒": { "codepoints": [8786], "characters": "\u2252" }, + "𝔢": { "codepoints": [120098], "characters": "\uD835\uDD22" }, + "⪚": { "codepoints": [10906], "characters": "\u2A9A" }, + "è": { "codepoints": [232], "characters": "\u00E8" }, + "è": { "codepoints": [232], "characters": "\u00E8" }, + "⪖": { "codepoints": [10902], "characters": "\u2A96" }, + "⪘": { "codepoints": [10904], "characters": "\u2A98" }, + "⪙": { "codepoints": [10905], "characters": "\u2A99" }, + "⏧": { "codepoints": [9191], "characters": "\u23E7" }, + "ℓ": { "codepoints": [8467], "characters": "\u2113" }, + "⪕": { "codepoints": [10901], "characters": "\u2A95" }, + "⪗": { "codepoints": [10903], "characters": "\u2A97" }, + "ē": { "codepoints": [275], "characters": "\u0113" }, + "∅": { "codepoints": [8709], "characters": "\u2205" }, + "∅": { "codepoints": [8709], "characters": "\u2205" }, + "∅": { "codepoints": [8709], "characters": "\u2205" }, + " ": { "codepoints": [8196], "characters": "\u2004" }, + " ": { "codepoints": [8197], "characters": "\u2005" }, + " ": { "codepoints": [8195], "characters": "\u2003" }, + "ŋ": { "codepoints": [331], "characters": "\u014B" }, + " ": { "codepoints": [8194], "characters": "\u2002" }, + "ę": { "codepoints": [281], "characters": "\u0119" }, + "𝕖": { "codepoints": [120150], "characters": "\uD835\uDD56" }, + "⋕": { "codepoints": [8917], "characters": "\u22D5" }, + "⧣": { "codepoints": [10723], "characters": "\u29E3" }, + "⩱": { "codepoints": [10865], "characters": "\u2A71" }, + "ε": { "codepoints": [949], "characters": "\u03B5" }, + "ε": { "codepoints": [949], "characters": "\u03B5" }, + "ϵ": { "codepoints": [1013], "characters": "\u03F5" }, + "≖": { "codepoints": [8790], "characters": "\u2256" }, + "≕": { "codepoints": [8789], "characters": "\u2255" }, + "≂": { "codepoints": [8770], "characters": "\u2242" }, + "⪖": { "codepoints": [10902], "characters": "\u2A96" }, + "⪕": { "codepoints": [10901], "characters": "\u2A95" }, + "=": { "codepoints": [61], "characters": "\u003D" }, + "≟": { "codepoints": [8799], "characters": "\u225F" }, + "≡": { "codepoints": [8801], "characters": "\u2261" }, + "⩸": { "codepoints": [10872], "characters": "\u2A78" }, + "⧥": { "codepoints": [10725], "characters": "\u29E5" }, + "≓": { "codepoints": [8787], "characters": "\u2253" }, + "⥱": { "codepoints": [10609], "characters": "\u2971" }, + "ℯ": { "codepoints": [8495], "characters": "\u212F" }, + "≐": { "codepoints": [8784], "characters": "\u2250" }, + "≂": { "codepoints": [8770], "characters": "\u2242" }, + "η": { "codepoints": [951], "characters": "\u03B7" }, + "ð": { "codepoints": [240], "characters": "\u00F0" }, + "ð": { "codepoints": [240], "characters": "\u00F0" }, + "ë": { "codepoints": [235], "characters": "\u00EB" }, + "ë": { "codepoints": [235], "characters": "\u00EB" }, + "€": { "codepoints": [8364], "characters": "\u20AC" }, + "!": { "codepoints": [33], "characters": "\u0021" }, + "∃": { "codepoints": [8707], "characters": "\u2203" }, + "ℰ": { "codepoints": [8496], "characters": "\u2130" }, + "ⅇ": { "codepoints": [8519], "characters": "\u2147" }, + "≒": { "codepoints": [8786], "characters": "\u2252" }, + "ф": { "codepoints": [1092], "characters": "\u0444" }, + "♀": { "codepoints": [9792], "characters": "\u2640" }, + "ffi": { "codepoints": [64259], "characters": "\uFB03" }, + "ff": { "codepoints": [64256], "characters": "\uFB00" }, + "ffl": { "codepoints": [64260], "characters": "\uFB04" }, + "𝔣": { "codepoints": [120099], "characters": "\uD835\uDD23" }, + "fi": { "codepoints": [64257], "characters": "\uFB01" }, + "fj": { "codepoints": [102, 106], "characters": "\u0066\u006A" }, + "♭": { "codepoints": [9837], "characters": "\u266D" }, + "fl": { "codepoints": [64258], "characters": "\uFB02" }, + "▱": { "codepoints": [9649], "characters": "\u25B1" }, + "ƒ": { "codepoints": [402], "characters": "\u0192" }, + "𝕗": { "codepoints": [120151], "characters": "\uD835\uDD57" }, + "∀": { "codepoints": [8704], "characters": "\u2200" }, + "⋔": { "codepoints": [8916], "characters": "\u22D4" }, + "⫙": { "codepoints": [10969], "characters": "\u2AD9" }, + "⨍": { "codepoints": [10765], "characters": "\u2A0D" }, + "½": { "codepoints": [189], "characters": "\u00BD" }, + "½": { "codepoints": [189], "characters": "\u00BD" }, + "⅓": { "codepoints": [8531], "characters": "\u2153" }, + "¼": { "codepoints": [188], "characters": "\u00BC" }, + "¼": { "codepoints": [188], "characters": "\u00BC" }, + "⅕": { "codepoints": [8533], "characters": "\u2155" }, + "⅙": { "codepoints": [8537], "characters": "\u2159" }, + "⅛": { "codepoints": [8539], "characters": "\u215B" }, + "⅔": { "codepoints": [8532], "characters": "\u2154" }, + "⅖": { "codepoints": [8534], "characters": "\u2156" }, + "¾": { "codepoints": [190], "characters": "\u00BE" }, + "¾": { "codepoints": [190], "characters": "\u00BE" }, + "⅗": { "codepoints": [8535], "characters": "\u2157" }, + "⅜": { "codepoints": [8540], "characters": "\u215C" }, + "⅘": { "codepoints": [8536], "characters": "\u2158" }, + "⅚": { "codepoints": [8538], "characters": "\u215A" }, + "⅝": { "codepoints": [8541], "characters": "\u215D" }, + "⅞": { "codepoints": [8542], "characters": "\u215E" }, + "⁄": { "codepoints": [8260], "characters": "\u2044" }, + "⌢": { "codepoints": [8994], "characters": "\u2322" }, + "𝒻": { "codepoints": [119995], "characters": "\uD835\uDCBB" }, + "≧": { "codepoints": [8807], "characters": "\u2267" }, + "⪌": { "codepoints": [10892], "characters": "\u2A8C" }, + "ǵ": { "codepoints": [501], "characters": "\u01F5" }, + "γ": { "codepoints": [947], "characters": "\u03B3" }, + "ϝ": { "codepoints": [989], "characters": "\u03DD" }, + "⪆": { "codepoints": [10886], "characters": "\u2A86" }, + "ğ": { "codepoints": [287], "characters": "\u011F" }, + "ĝ": { "codepoints": [285], "characters": "\u011D" }, + "г": { "codepoints": [1075], "characters": "\u0433" }, + "ġ": { "codepoints": [289], "characters": "\u0121" }, + "≥": { "codepoints": [8805], "characters": "\u2265" }, + "⋛": { "codepoints": [8923], "characters": "\u22DB" }, + "≥": { "codepoints": [8805], "characters": "\u2265" }, + "≧": { "codepoints": [8807], "characters": "\u2267" }, + "⩾": { "codepoints": [10878], "characters": "\u2A7E" }, + "⩾": { "codepoints": [10878], "characters": "\u2A7E" }, + "⪩": { "codepoints": [10921], "characters": "\u2AA9" }, + "⪀": { "codepoints": [10880], "characters": "\u2A80" }, + "⪂": { "codepoints": [10882], "characters": "\u2A82" }, + "⪄": { "codepoints": [10884], "characters": "\u2A84" }, + "⋛︀": { "codepoints": [8923, 65024], "characters": "\u22DB\uFE00" }, + "⪔": { "codepoints": [10900], "characters": "\u2A94" }, + "𝔤": { "codepoints": [120100], "characters": "\uD835\uDD24" }, + "≫": { "codepoints": [8811], "characters": "\u226B" }, + "⋙": { "codepoints": [8921], "characters": "\u22D9" }, + "ℷ": { "codepoints": [8503], "characters": "\u2137" }, + "ѓ": { "codepoints": [1107], "characters": "\u0453" }, + "≷": { "codepoints": [8823], "characters": "\u2277" }, + "⪒": { "codepoints": [10898], "characters": "\u2A92" }, + "⪥": { "codepoints": [10917], "characters": "\u2AA5" }, + "⪤": { "codepoints": [10916], "characters": "\u2AA4" }, + "≩": { "codepoints": [8809], "characters": "\u2269" }, + "⪊": { "codepoints": [10890], "characters": "\u2A8A" }, + "⪊": { "codepoints": [10890], "characters": "\u2A8A" }, + "⪈": { "codepoints": [10888], "characters": "\u2A88" }, + "⪈": { "codepoints": [10888], "characters": "\u2A88" }, + "≩": { "codepoints": [8809], "characters": "\u2269" }, + "⋧": { "codepoints": [8935], "characters": "\u22E7" }, + "𝕘": { "codepoints": [120152], "characters": "\uD835\uDD58" }, + "`": { "codepoints": [96], "characters": "\u0060" }, + "ℊ": { "codepoints": [8458], "characters": "\u210A" }, + "≳": { "codepoints": [8819], "characters": "\u2273" }, + "⪎": { "codepoints": [10894], "characters": "\u2A8E" }, + "⪐": { "codepoints": [10896], "characters": "\u2A90" }, + ">": { "codepoints": [62], "characters": "\u003E" }, + ">": { "codepoints": [62], "characters": "\u003E" }, + "⪧": { "codepoints": [10919], "characters": "\u2AA7" }, + "⩺": { "codepoints": [10874], "characters": "\u2A7A" }, + "⋗": { "codepoints": [8919], "characters": "\u22D7" }, + "⦕": { "codepoints": [10645], "characters": "\u2995" }, + "⩼": { "codepoints": [10876], "characters": "\u2A7C" }, + "⪆": { "codepoints": [10886], "characters": "\u2A86" }, + "⥸": { "codepoints": [10616], "characters": "\u2978" }, + "⋗": { "codepoints": [8919], "characters": "\u22D7" }, + "⋛": { "codepoints": [8923], "characters": "\u22DB" }, + "⪌": { "codepoints": [10892], "characters": "\u2A8C" }, + "≷": { "codepoints": [8823], "characters": "\u2277" }, + "≳": { "codepoints": [8819], "characters": "\u2273" }, + "≩︀": { "codepoints": [8809, 65024], "characters": "\u2269\uFE00" }, + "≩︀": { "codepoints": [8809, 65024], "characters": "\u2269\uFE00" }, + "⇔": { "codepoints": [8660], "characters": "\u21D4" }, + " ": { "codepoints": [8202], "characters": "\u200A" }, + "½": { "codepoints": [189], "characters": "\u00BD" }, + "ℋ": { "codepoints": [8459], "characters": "\u210B" }, + "ъ": { "codepoints": [1098], "characters": "\u044A" }, + "↔": { "codepoints": [8596], "characters": "\u2194" }, + "⥈": { "codepoints": [10568], "characters": "\u2948" }, + "↭": { "codepoints": [8621], "characters": "\u21AD" }, + "ℏ": { "codepoints": [8463], "characters": "\u210F" }, + "ĥ": { "codepoints": [293], "characters": "\u0125" }, + "♥": { "codepoints": [9829], "characters": "\u2665" }, + "♥": { "codepoints": [9829], "characters": "\u2665" }, + "…": { "codepoints": [8230], "characters": "\u2026" }, + "⊹": { "codepoints": [8889], "characters": "\u22B9" }, + "𝔥": { "codepoints": [120101], "characters": "\uD835\uDD25" }, + "⤥": { "codepoints": [10533], "characters": "\u2925" }, + "⤦": { "codepoints": [10534], "characters": "\u2926" }, + "⇿": { "codepoints": [8703], "characters": "\u21FF" }, + "∻": { "codepoints": [8763], "characters": "\u223B" }, + "↩": { "codepoints": [8617], "characters": "\u21A9" }, + "↪": { "codepoints": [8618], "characters": "\u21AA" }, + "𝕙": { "codepoints": [120153], "characters": "\uD835\uDD59" }, + "―": { "codepoints": [8213], "characters": "\u2015" }, + "𝒽": { "codepoints": [119997], "characters": "\uD835\uDCBD" }, + "ℏ": { "codepoints": [8463], "characters": "\u210F" }, + "ħ": { "codepoints": [295], "characters": "\u0127" }, + "⁃": { "codepoints": [8259], "characters": "\u2043" }, + "‐": { "codepoints": [8208], "characters": "\u2010" }, + "í": { "codepoints": [237], "characters": "\u00ED" }, + "í": { "codepoints": [237], "characters": "\u00ED" }, + "⁣": { "codepoints": [8291], "characters": "\u2063" }, + "î": { "codepoints": [238], "characters": "\u00EE" }, + "î": { "codepoints": [238], "characters": "\u00EE" }, + "и": { "codepoints": [1080], "characters": "\u0438" }, + "е": { "codepoints": [1077], "characters": "\u0435" }, + "¡": { "codepoints": [161], "characters": "\u00A1" }, + "¡": { "codepoints": [161], "characters": "\u00A1" }, + "⇔": { "codepoints": [8660], "characters": "\u21D4" }, + "𝔦": { "codepoints": [120102], "characters": "\uD835\uDD26" }, + "ì": { "codepoints": [236], "characters": "\u00EC" }, + "ì": { "codepoints": [236], "characters": "\u00EC" }, + "ⅈ": { "codepoints": [8520], "characters": "\u2148" }, + "⨌": { "codepoints": [10764], "characters": "\u2A0C" }, + "∭": { "codepoints": [8749], "characters": "\u222D" }, + "⧜": { "codepoints": [10716], "characters": "\u29DC" }, + "℩": { "codepoints": [8489], "characters": "\u2129" }, + "ij": { "codepoints": [307], "characters": "\u0133" }, + "ī": { "codepoints": [299], "characters": "\u012B" }, + "ℑ": { "codepoints": [8465], "characters": "\u2111" }, + "ℐ": { "codepoints": [8464], "characters": "\u2110" }, + "ℑ": { "codepoints": [8465], "characters": "\u2111" }, + "ı": { "codepoints": [305], "characters": "\u0131" }, + "⊷": { "codepoints": [8887], "characters": "\u22B7" }, + "Ƶ": { "codepoints": [437], "characters": "\u01B5" }, + "∈": { "codepoints": [8712], "characters": "\u2208" }, + "℅": { "codepoints": [8453], "characters": "\u2105" }, + "∞": { "codepoints": [8734], "characters": "\u221E" }, + "⧝": { "codepoints": [10717], "characters": "\u29DD" }, + "ı": { "codepoints": [305], "characters": "\u0131" }, + "∫": { "codepoints": [8747], "characters": "\u222B" }, + "⊺": { "codepoints": [8890], "characters": "\u22BA" }, + "ℤ": { "codepoints": [8484], "characters": "\u2124" }, + "⊺": { "codepoints": [8890], "characters": "\u22BA" }, + "⨗": { "codepoints": [10775], "characters": "\u2A17" }, + "⨼": { "codepoints": [10812], "characters": "\u2A3C" }, + "ё": { "codepoints": [1105], "characters": "\u0451" }, + "į": { "codepoints": [303], "characters": "\u012F" }, + "𝕚": { "codepoints": [120154], "characters": "\uD835\uDD5A" }, + "ι": { "codepoints": [953], "characters": "\u03B9" }, + "⨼": { "codepoints": [10812], "characters": "\u2A3C" }, + "¿": { "codepoints": [191], "characters": "\u00BF" }, + "¿": { "codepoints": [191], "characters": "\u00BF" }, + "𝒾": { "codepoints": [119998], "characters": "\uD835\uDCBE" }, + "∈": { "codepoints": [8712], "characters": "\u2208" }, + "⋹": { "codepoints": [8953], "characters": "\u22F9" }, + "⋵": { "codepoints": [8949], "characters": "\u22F5" }, + "⋴": { "codepoints": [8948], "characters": "\u22F4" }, + "⋳": { "codepoints": [8947], "characters": "\u22F3" }, + "∈": { "codepoints": [8712], "characters": "\u2208" }, + "⁢": { "codepoints": [8290], "characters": "\u2062" }, + "ĩ": { "codepoints": [297], "characters": "\u0129" }, + "і": { "codepoints": [1110], "characters": "\u0456" }, + "ï": { "codepoints": [239], "characters": "\u00EF" }, + "ï": { "codepoints": [239], "characters": "\u00EF" }, + "ĵ": { "codepoints": [309], "characters": "\u0135" }, + "й": { "codepoints": [1081], "characters": "\u0439" }, + "𝔧": { "codepoints": [120103], "characters": "\uD835\uDD27" }, + "ȷ": { "codepoints": [567], "characters": "\u0237" }, + "𝕛": { "codepoints": [120155], "characters": "\uD835\uDD5B" }, + "𝒿": { "codepoints": [119999], "characters": "\uD835\uDCBF" }, + "ј": { "codepoints": [1112], "characters": "\u0458" }, + "є": { "codepoints": [1108], "characters": "\u0454" }, + "κ": { "codepoints": [954], "characters": "\u03BA" }, + "ϰ": { "codepoints": [1008], "characters": "\u03F0" }, + "ķ": { "codepoints": [311], "characters": "\u0137" }, + "к": { "codepoints": [1082], "characters": "\u043A" }, + "𝔨": { "codepoints": [120104], "characters": "\uD835\uDD28" }, + "ĸ": { "codepoints": [312], "characters": "\u0138" }, + "х": { "codepoints": [1093], "characters": "\u0445" }, + "ќ": { "codepoints": [1116], "characters": "\u045C" }, + "𝕜": { "codepoints": [120156], "characters": "\uD835\uDD5C" }, + "𝓀": { "codepoints": [120000], "characters": "\uD835\uDCC0" }, + "⇚": { "codepoints": [8666], "characters": "\u21DA" }, + "⇐": { "codepoints": [8656], "characters": "\u21D0" }, + "⤛": { "codepoints": [10523], "characters": "\u291B" }, + "⤎": { "codepoints": [10510], "characters": "\u290E" }, + "≦": { "codepoints": [8806], "characters": "\u2266" }, + "⪋": { "codepoints": [10891], "characters": "\u2A8B" }, + "⥢": { "codepoints": [10594], "characters": "\u2962" }, + "ĺ": { "codepoints": [314], "characters": "\u013A" }, + "⦴": { "codepoints": [10676], "characters": "\u29B4" }, + "ℒ": { "codepoints": [8466], "characters": "\u2112" }, + "λ": { "codepoints": [955], "characters": "\u03BB" }, + "⟨": { "codepoints": [10216], "characters": "\u27E8" }, + "⦑": { "codepoints": [10641], "characters": "\u2991" }, + "⟨": { "codepoints": [10216], "characters": "\u27E8" }, + "⪅": { "codepoints": [10885], "characters": "\u2A85" }, + "«": { "codepoints": [171], "characters": "\u00AB" }, + "«": { "codepoints": [171], "characters": "\u00AB" }, + "←": { "codepoints": [8592], "characters": "\u2190" }, + "⇤": { "codepoints": [8676], "characters": "\u21E4" }, + "⤟": { "codepoints": [10527], "characters": "\u291F" }, + "⤝": { "codepoints": [10525], "characters": "\u291D" }, + "↩": { "codepoints": [8617], "characters": "\u21A9" }, + "↫": { "codepoints": [8619], "characters": "\u21AB" }, + "⤹": { "codepoints": [10553], "characters": "\u2939" }, + "⥳": { "codepoints": [10611], "characters": "\u2973" }, + "↢": { "codepoints": [8610], "characters": "\u21A2" }, + "⪫": { "codepoints": [10923], "characters": "\u2AAB" }, + "⤙": { "codepoints": [10521], "characters": "\u2919" }, + "⪭": { "codepoints": [10925], "characters": "\u2AAD" }, + "⪭︀": { "codepoints": [10925, 65024], "characters": "\u2AAD\uFE00" }, + "⤌": { "codepoints": [10508], "characters": "\u290C" }, + "❲": { "codepoints": [10098], "characters": "\u2772" }, + "{": { "codepoints": [123], "characters": "\u007B" }, + "[": { "codepoints": [91], "characters": "\u005B" }, + "⦋": { "codepoints": [10635], "characters": "\u298B" }, + "⦏": { "codepoints": [10639], "characters": "\u298F" }, + "⦍": { "codepoints": [10637], "characters": "\u298D" }, + "ľ": { "codepoints": [318], "characters": "\u013E" }, + "ļ": { "codepoints": [316], "characters": "\u013C" }, + "⌈": { "codepoints": [8968], "characters": "\u2308" }, + "{": { "codepoints": [123], "characters": "\u007B" }, + "л": { "codepoints": [1083], "characters": "\u043B" }, + "⤶": { "codepoints": [10550], "characters": "\u2936" }, + "“": { "codepoints": [8220], "characters": "\u201C" }, + "„": { "codepoints": [8222], "characters": "\u201E" }, + "⥧": { "codepoints": [10599], "characters": "\u2967" }, + "⥋": { "codepoints": [10571], "characters": "\u294B" }, + "↲": { "codepoints": [8626], "characters": "\u21B2" }, + "≤": { "codepoints": [8804], "characters": "\u2264" }, + "←": { "codepoints": [8592], "characters": "\u2190" }, + "↢": { "codepoints": [8610], "characters": "\u21A2" }, + "↽": { "codepoints": [8637], "characters": "\u21BD" }, + "↼": { "codepoints": [8636], "characters": "\u21BC" }, + "⇇": { "codepoints": [8647], "characters": "\u21C7" }, + "↔": { "codepoints": [8596], "characters": "\u2194" }, + "⇆": { "codepoints": [8646], "characters": "\u21C6" }, + "⇋": { "codepoints": [8651], "characters": "\u21CB" }, + "↭": { "codepoints": [8621], "characters": "\u21AD" }, + "⋋": { "codepoints": [8907], "characters": "\u22CB" }, + "⋚": { "codepoints": [8922], "characters": "\u22DA" }, + "≤": { "codepoints": [8804], "characters": "\u2264" }, + "≦": { "codepoints": [8806], "characters": "\u2266" }, + "⩽": { "codepoints": [10877], "characters": "\u2A7D" }, + "⩽": { "codepoints": [10877], "characters": "\u2A7D" }, + "⪨": { "codepoints": [10920], "characters": "\u2AA8" }, + "⩿": { "codepoints": [10879], "characters": "\u2A7F" }, + "⪁": { "codepoints": [10881], "characters": "\u2A81" }, + "⪃": { "codepoints": [10883], "characters": "\u2A83" }, + "⋚︀": { "codepoints": [8922, 65024], "characters": "\u22DA\uFE00" }, + "⪓": { "codepoints": [10899], "characters": "\u2A93" }, + "⪅": { "codepoints": [10885], "characters": "\u2A85" }, + "⋖": { "codepoints": [8918], "characters": "\u22D6" }, + "⋚": { "codepoints": [8922], "characters": "\u22DA" }, + "⪋": { "codepoints": [10891], "characters": "\u2A8B" }, + "≶": { "codepoints": [8822], "characters": "\u2276" }, + "≲": { "codepoints": [8818], "characters": "\u2272" }, + "⥼": { "codepoints": [10620], "characters": "\u297C" }, + "⌊": { "codepoints": [8970], "characters": "\u230A" }, + "𝔩": { "codepoints": [120105], "characters": "\uD835\uDD29" }, + "≶": { "codepoints": [8822], "characters": "\u2276" }, + "⪑": { "codepoints": [10897], "characters": "\u2A91" }, + "↽": { "codepoints": [8637], "characters": "\u21BD" }, + "↼": { "codepoints": [8636], "characters": "\u21BC" }, + "⥪": { "codepoints": [10602], "characters": "\u296A" }, + "▄": { "codepoints": [9604], "characters": "\u2584" }, + "љ": { "codepoints": [1113], "characters": "\u0459" }, + "≪": { "codepoints": [8810], "characters": "\u226A" }, + "⇇": { "codepoints": [8647], "characters": "\u21C7" }, + "⌞": { "codepoints": [8990], "characters": "\u231E" }, + "⥫": { "codepoints": [10603], "characters": "\u296B" }, + "◺": { "codepoints": [9722], "characters": "\u25FA" }, + "ŀ": { "codepoints": [320], "characters": "\u0140" }, + "⎰": { "codepoints": [9136], "characters": "\u23B0" }, + "⎰": { "codepoints": [9136], "characters": "\u23B0" }, + "≨": { "codepoints": [8808], "characters": "\u2268" }, + "⪉": { "codepoints": [10889], "characters": "\u2A89" }, + "⪉": { "codepoints": [10889], "characters": "\u2A89" }, + "⪇": { "codepoints": [10887], "characters": "\u2A87" }, + "⪇": { "codepoints": [10887], "characters": "\u2A87" }, + "≨": { "codepoints": [8808], "characters": "\u2268" }, + "⋦": { "codepoints": [8934], "characters": "\u22E6" }, + "⟬": { "codepoints": [10220], "characters": "\u27EC" }, + "⇽": { "codepoints": [8701], "characters": "\u21FD" }, + "⟦": { "codepoints": [10214], "characters": "\u27E6" }, + "⟵": { "codepoints": [10229], "characters": "\u27F5" }, + "⟷": { "codepoints": [10231], "characters": "\u27F7" }, + "⟼": { "codepoints": [10236], "characters": "\u27FC" }, + "⟶": { "codepoints": [10230], "characters": "\u27F6" }, + "↫": { "codepoints": [8619], "characters": "\u21AB" }, + "↬": { "codepoints": [8620], "characters": "\u21AC" }, + "⦅": { "codepoints": [10629], "characters": "\u2985" }, + "𝕝": { "codepoints": [120157], "characters": "\uD835\uDD5D" }, + "⨭": { "codepoints": [10797], "characters": "\u2A2D" }, + "⨴": { "codepoints": [10804], "characters": "\u2A34" }, + "∗": { "codepoints": [8727], "characters": "\u2217" }, + "_": { "codepoints": [95], "characters": "\u005F" }, + "◊": { "codepoints": [9674], "characters": "\u25CA" }, + "◊": { "codepoints": [9674], "characters": "\u25CA" }, + "⧫": { "codepoints": [10731], "characters": "\u29EB" }, + "(": { "codepoints": [40], "characters": "\u0028" }, + "⦓": { "codepoints": [10643], "characters": "\u2993" }, + "⇆": { "codepoints": [8646], "characters": "\u21C6" }, + "⌟": { "codepoints": [8991], "characters": "\u231F" }, + "⇋": { "codepoints": [8651], "characters": "\u21CB" }, + "⥭": { "codepoints": [10605], "characters": "\u296D" }, + "‎": { "codepoints": [8206], "characters": "\u200E" }, + "⊿": { "codepoints": [8895], "characters": "\u22BF" }, + "‹": { "codepoints": [8249], "characters": "\u2039" }, + "𝓁": { "codepoints": [120001], "characters": "\uD835\uDCC1" }, + "↰": { "codepoints": [8624], "characters": "\u21B0" }, + "≲": { "codepoints": [8818], "characters": "\u2272" }, + "⪍": { "codepoints": [10893], "characters": "\u2A8D" }, + "⪏": { "codepoints": [10895], "characters": "\u2A8F" }, + "[": { "codepoints": [91], "characters": "\u005B" }, + "‘": { "codepoints": [8216], "characters": "\u2018" }, + "‚": { "codepoints": [8218], "characters": "\u201A" }, + "ł": { "codepoints": [322], "characters": "\u0142" }, + "<": { "codepoints": [60], "characters": "\u003C" }, + "<": { "codepoints": [60], "characters": "\u003C" }, + "⪦": { "codepoints": [10918], "characters": "\u2AA6" }, + "⩹": { "codepoints": [10873], "characters": "\u2A79" }, + "⋖": { "codepoints": [8918], "characters": "\u22D6" }, + "⋋": { "codepoints": [8907], "characters": "\u22CB" }, + "⋉": { "codepoints": [8905], "characters": "\u22C9" }, + "⥶": { "codepoints": [10614], "characters": "\u2976" }, + "⩻": { "codepoints": [10875], "characters": "\u2A7B" }, + "⦖": { "codepoints": [10646], "characters": "\u2996" }, + "◃": { "codepoints": [9667], "characters": "\u25C3" }, + "⊴": { "codepoints": [8884], "characters": "\u22B4" }, + "◂": { "codepoints": [9666], "characters": "\u25C2" }, + "⥊": { "codepoints": [10570], "characters": "\u294A" }, + "⥦": { "codepoints": [10598], "characters": "\u2966" }, + "≨︀": { "codepoints": [8808, 65024], "characters": "\u2268\uFE00" }, + "≨︀": { "codepoints": [8808, 65024], "characters": "\u2268\uFE00" }, + "∺": { "codepoints": [8762], "characters": "\u223A" }, + "¯": { "codepoints": [175], "characters": "\u00AF" }, + "¯": { "codepoints": [175], "characters": "\u00AF" }, + "♂": { "codepoints": [9794], "characters": "\u2642" }, + "✠": { "codepoints": [10016], "characters": "\u2720" }, + "✠": { "codepoints": [10016], "characters": "\u2720" }, + "↦": { "codepoints": [8614], "characters": "\u21A6" }, + "↦": { "codepoints": [8614], "characters": "\u21A6" }, + "↧": { "codepoints": [8615], "characters": "\u21A7" }, + "↤": { "codepoints": [8612], "characters": "\u21A4" }, + "↥": { "codepoints": [8613], "characters": "\u21A5" }, + "▮": { "codepoints": [9646], "characters": "\u25AE" }, + "⨩": { "codepoints": [10793], "characters": "\u2A29" }, + "м": { "codepoints": [1084], "characters": "\u043C" }, + "—": { "codepoints": [8212], "characters": "\u2014" }, + "∡": { "codepoints": [8737], "characters": "\u2221" }, + "𝔪": { "codepoints": [120106], "characters": "\uD835\uDD2A" }, + "℧": { "codepoints": [8487], "characters": "\u2127" }, + "µ": { "codepoints": [181], "characters": "\u00B5" }, + "µ": { "codepoints": [181], "characters": "\u00B5" }, + "∣": { "codepoints": [8739], "characters": "\u2223" }, + "*": { "codepoints": [42], "characters": "\u002A" }, + "⫰": { "codepoints": [10992], "characters": "\u2AF0" }, + "·": { "codepoints": [183], "characters": "\u00B7" }, + "·": { "codepoints": [183], "characters": "\u00B7" }, + "−": { "codepoints": [8722], "characters": "\u2212" }, + "⊟": { "codepoints": [8863], "characters": "\u229F" }, + "∸": { "codepoints": [8760], "characters": "\u2238" }, + "⨪": { "codepoints": [10794], "characters": "\u2A2A" }, + "⫛": { "codepoints": [10971], "characters": "\u2ADB" }, + "…": { "codepoints": [8230], "characters": "\u2026" }, + "∓": { "codepoints": [8723], "characters": "\u2213" }, + "⊧": { "codepoints": [8871], "characters": "\u22A7" }, + "𝕞": { "codepoints": [120158], "characters": "\uD835\uDD5E" }, + "∓": { "codepoints": [8723], "characters": "\u2213" }, + "𝓂": { "codepoints": [120002], "characters": "\uD835\uDCC2" }, + "∾": { "codepoints": [8766], "characters": "\u223E" }, + "μ": { "codepoints": [956], "characters": "\u03BC" }, + "⊸": { "codepoints": [8888], "characters": "\u22B8" }, + "⊸": { "codepoints": [8888], "characters": "\u22B8" }, + "⋙̸": { "codepoints": [8921, 824], "characters": "\u22D9\u0338" }, + "≫⃒": { "codepoints": [8811, 8402], "characters": "\u226B\u20D2" }, + "≫̸": { "codepoints": [8811, 824], "characters": "\u226B\u0338" }, + "⇍": { "codepoints": [8653], "characters": "\u21CD" }, + "⇎": { "codepoints": [8654], "characters": "\u21CE" }, + "⋘̸": { "codepoints": [8920, 824], "characters": "\u22D8\u0338" }, + "≪⃒": { "codepoints": [8810, 8402], "characters": "\u226A\u20D2" }, + "≪̸": { "codepoints": [8810, 824], "characters": "\u226A\u0338" }, + "⇏": { "codepoints": [8655], "characters": "\u21CF" }, + "⊯": { "codepoints": [8879], "characters": "\u22AF" }, + "⊮": { "codepoints": [8878], "characters": "\u22AE" }, + "∇": { "codepoints": [8711], "characters": "\u2207" }, + "ń": { "codepoints": [324], "characters": "\u0144" }, + "∠⃒": { "codepoints": [8736, 8402], "characters": "\u2220\u20D2" }, + "≉": { "codepoints": [8777], "characters": "\u2249" }, + "⩰̸": { "codepoints": [10864, 824], "characters": "\u2A70\u0338" }, + "≋̸": { "codepoints": [8779, 824], "characters": "\u224B\u0338" }, + "ʼn": { "codepoints": [329], "characters": "\u0149" }, + "≉": { "codepoints": [8777], "characters": "\u2249" }, + "♮": { "codepoints": [9838], "characters": "\u266E" }, + "♮": { "codepoints": [9838], "characters": "\u266E" }, + "ℕ": { "codepoints": [8469], "characters": "\u2115" }, + " ": { "codepoints": [160], "characters": "\u00A0" }, + " ": { "codepoints": [160], "characters": "\u00A0" }, + "≎̸": { "codepoints": [8782, 824], "characters": "\u224E\u0338" }, + "≏̸": { "codepoints": [8783, 824], "characters": "\u224F\u0338" }, + "⩃": { "codepoints": [10819], "characters": "\u2A43" }, + "ň": { "codepoints": [328], "characters": "\u0148" }, + "ņ": { "codepoints": [326], "characters": "\u0146" }, + "≇": { "codepoints": [8775], "characters": "\u2247" }, + "⩭̸": { "codepoints": [10861, 824], "characters": "\u2A6D\u0338" }, + "⩂": { "codepoints": [10818], "characters": "\u2A42" }, + "н": { "codepoints": [1085], "characters": "\u043D" }, + "–": { "codepoints": [8211], "characters": "\u2013" }, + "≠": { "codepoints": [8800], "characters": "\u2260" }, + "⇗": { "codepoints": [8663], "characters": "\u21D7" }, + "⤤": { "codepoints": [10532], "characters": "\u2924" }, + "↗": { "codepoints": [8599], "characters": "\u2197" }, + "↗": { "codepoints": [8599], "characters": "\u2197" }, + "≐̸": { "codepoints": [8784, 824], "characters": "\u2250\u0338" }, + "≢": { "codepoints": [8802], "characters": "\u2262" }, + "⤨": { "codepoints": [10536], "characters": "\u2928" }, + "≂̸": { "codepoints": [8770, 824], "characters": "\u2242\u0338" }, + "∄": { "codepoints": [8708], "characters": "\u2204" }, + "∄": { "codepoints": [8708], "characters": "\u2204" }, + "𝔫": { "codepoints": [120107], "characters": "\uD835\uDD2B" }, + "≧̸": { "codepoints": [8807, 824], "characters": "\u2267\u0338" }, + "≱": { "codepoints": [8817], "characters": "\u2271" }, + "≱": { "codepoints": [8817], "characters": "\u2271" }, + "≧̸": { "codepoints": [8807, 824], "characters": "\u2267\u0338" }, + "⩾̸": { "codepoints": [10878, 824], "characters": "\u2A7E\u0338" }, + "⩾̸": { "codepoints": [10878, 824], "characters": "\u2A7E\u0338" }, + "≵": { "codepoints": [8821], "characters": "\u2275" }, + "≯": { "codepoints": [8815], "characters": "\u226F" }, + "≯": { "codepoints": [8815], "characters": "\u226F" }, + "⇎": { "codepoints": [8654], "characters": "\u21CE" }, + "↮": { "codepoints": [8622], "characters": "\u21AE" }, + "⫲": { "codepoints": [10994], "characters": "\u2AF2" }, + "∋": { "codepoints": [8715], "characters": "\u220B" }, + "⋼": { "codepoints": [8956], "characters": "\u22FC" }, + "⋺": { "codepoints": [8954], "characters": "\u22FA" }, + "∋": { "codepoints": [8715], "characters": "\u220B" }, + "њ": { "codepoints": [1114], "characters": "\u045A" }, + "⇍": { "codepoints": [8653], "characters": "\u21CD" }, + "≦̸": { "codepoints": [8806, 824], "characters": "\u2266\u0338" }, + "↚": { "codepoints": [8602], "characters": "\u219A" }, + "‥": { "codepoints": [8229], "characters": "\u2025" }, + "≰": { "codepoints": [8816], "characters": "\u2270" }, + "↚": { "codepoints": [8602], "characters": "\u219A" }, + "↮": { "codepoints": [8622], "characters": "\u21AE" }, + "≰": { "codepoints": [8816], "characters": "\u2270" }, + "≦̸": { "codepoints": [8806, 824], "characters": "\u2266\u0338" }, + "⩽̸": { "codepoints": [10877, 824], "characters": "\u2A7D\u0338" }, + "⩽̸": { "codepoints": [10877, 824], "characters": "\u2A7D\u0338" }, + "≮": { "codepoints": [8814], "characters": "\u226E" }, + "≴": { "codepoints": [8820], "characters": "\u2274" }, + "≮": { "codepoints": [8814], "characters": "\u226E" }, + "⋪": { "codepoints": [8938], "characters": "\u22EA" }, + "⋬": { "codepoints": [8940], "characters": "\u22EC" }, + "∤": { "codepoints": [8740], "characters": "\u2224" }, + "𝕟": { "codepoints": [120159], "characters": "\uD835\uDD5F" }, + "¬": { "codepoints": [172], "characters": "\u00AC" }, + "¬": { "codepoints": [172], "characters": "\u00AC" }, + "∉": { "codepoints": [8713], "characters": "\u2209" }, + "⋹̸": { "codepoints": [8953, 824], "characters": "\u22F9\u0338" }, + "⋵̸": { "codepoints": [8949, 824], "characters": "\u22F5\u0338" }, + "∉": { "codepoints": [8713], "characters": "\u2209" }, + "⋷": { "codepoints": [8951], "characters": "\u22F7" }, + "⋶": { "codepoints": [8950], "characters": "\u22F6" }, + "∌": { "codepoints": [8716], "characters": "\u220C" }, + "∌": { "codepoints": [8716], "characters": "\u220C" }, + "⋾": { "codepoints": [8958], "characters": "\u22FE" }, + "⋽": { "codepoints": [8957], "characters": "\u22FD" }, + "∦": { "codepoints": [8742], "characters": "\u2226" }, + "∦": { "codepoints": [8742], "characters": "\u2226" }, + "⫽⃥": { "codepoints": [11005, 8421], "characters": "\u2AFD\u20E5" }, + "∂̸": { "codepoints": [8706, 824], "characters": "\u2202\u0338" }, + "⨔": { "codepoints": [10772], "characters": "\u2A14" }, + "⊀": { "codepoints": [8832], "characters": "\u2280" }, + "⋠": { "codepoints": [8928], "characters": "\u22E0" }, + "⪯̸": { "codepoints": [10927, 824], "characters": "\u2AAF\u0338" }, + "⊀": { "codepoints": [8832], "characters": "\u2280" }, + "⪯̸": { "codepoints": [10927, 824], "characters": "\u2AAF\u0338" }, + "⇏": { "codepoints": [8655], "characters": "\u21CF" }, + "↛": { "codepoints": [8603], "characters": "\u219B" }, + "⤳̸": { "codepoints": [10547, 824], "characters": "\u2933\u0338" }, + "↝̸": { "codepoints": [8605, 824], "characters": "\u219D\u0338" }, + "↛": { "codepoints": [8603], "characters": "\u219B" }, + "⋫": { "codepoints": [8939], "characters": "\u22EB" }, + "⋭": { "codepoints": [8941], "characters": "\u22ED" }, + "⊁": { "codepoints": [8833], "characters": "\u2281" }, + "⋡": { "codepoints": [8929], "characters": "\u22E1" }, + "⪰̸": { "codepoints": [10928, 824], "characters": "\u2AB0\u0338" }, + "𝓃": { "codepoints": [120003], "characters": "\uD835\uDCC3" }, + "∤": { "codepoints": [8740], "characters": "\u2224" }, + "∦": { "codepoints": [8742], "characters": "\u2226" }, + "≁": { "codepoints": [8769], "characters": "\u2241" }, + "≄": { "codepoints": [8772], "characters": "\u2244" }, + "≄": { "codepoints": [8772], "characters": "\u2244" }, + "∤": { "codepoints": [8740], "characters": "\u2224" }, + "∦": { "codepoints": [8742], "characters": "\u2226" }, + "⋢": { "codepoints": [8930], "characters": "\u22E2" }, + "⋣": { "codepoints": [8931], "characters": "\u22E3" }, + "⊄": { "codepoints": [8836], "characters": "\u2284" }, + "⫅̸": { "codepoints": [10949, 824], "characters": "\u2AC5\u0338" }, + "⊈": { "codepoints": [8840], "characters": "\u2288" }, + "⊂⃒": { "codepoints": [8834, 8402], "characters": "\u2282\u20D2" }, + "⊈": { "codepoints": [8840], "characters": "\u2288" }, + "⫅̸": { "codepoints": [10949, 824], "characters": "\u2AC5\u0338" }, + "⊁": { "codepoints": [8833], "characters": "\u2281" }, + "⪰̸": { "codepoints": [10928, 824], "characters": "\u2AB0\u0338" }, + "⊅": { "codepoints": [8837], "characters": "\u2285" }, + "⫆̸": { "codepoints": [10950, 824], "characters": "\u2AC6\u0338" }, + "⊉": { "codepoints": [8841], "characters": "\u2289" }, + "⊃⃒": { "codepoints": [8835, 8402], "characters": "\u2283\u20D2" }, + "⊉": { "codepoints": [8841], "characters": "\u2289" }, + "⫆̸": { "codepoints": [10950, 824], "characters": "\u2AC6\u0338" }, + "≹": { "codepoints": [8825], "characters": "\u2279" }, + "ñ": { "codepoints": [241], "characters": "\u00F1" }, + "ñ": { "codepoints": [241], "characters": "\u00F1" }, + "≸": { "codepoints": [8824], "characters": "\u2278" }, + "⋪": { "codepoints": [8938], "characters": "\u22EA" }, + "⋬": { "codepoints": [8940], "characters": "\u22EC" }, + "⋫": { "codepoints": [8939], "characters": "\u22EB" }, + "⋭": { "codepoints": [8941], "characters": "\u22ED" }, + "ν": { "codepoints": [957], "characters": "\u03BD" }, + "#": { "codepoints": [35], "characters": "\u0023" }, + "№": { "codepoints": [8470], "characters": "\u2116" }, + " ": { "codepoints": [8199], "characters": "\u2007" }, + "⊭": { "codepoints": [8877], "characters": "\u22AD" }, + "⤄": { "codepoints": [10500], "characters": "\u2904" }, + "≍⃒": { "codepoints": [8781, 8402], "characters": "\u224D\u20D2" }, + "⊬": { "codepoints": [8876], "characters": "\u22AC" }, + "≥⃒": { "codepoints": [8805, 8402], "characters": "\u2265\u20D2" }, + ">⃒": { "codepoints": [62, 8402], "characters": "\u003E\u20D2" }, + "⧞": { "codepoints": [10718], "characters": "\u29DE" }, + "⤂": { "codepoints": [10498], "characters": "\u2902" }, + "≤⃒": { "codepoints": [8804, 8402], "characters": "\u2264\u20D2" }, + "<⃒": { "codepoints": [60, 8402], "characters": "\u003C\u20D2" }, + "⊴⃒": { "codepoints": [8884, 8402], "characters": "\u22B4\u20D2" }, + "⤃": { "codepoints": [10499], "characters": "\u2903" }, + "⊵⃒": { "codepoints": [8885, 8402], "characters": "\u22B5\u20D2" }, + "∼⃒": { "codepoints": [8764, 8402], "characters": "\u223C\u20D2" }, + "⇖": { "codepoints": [8662], "characters": "\u21D6" }, + "⤣": { "codepoints": [10531], "characters": "\u2923" }, + "↖": { "codepoints": [8598], "characters": "\u2196" }, + "↖": { "codepoints": [8598], "characters": "\u2196" }, + "⤧": { "codepoints": [10535], "characters": "\u2927" }, + "Ⓢ": { "codepoints": [9416], "characters": "\u24C8" }, + "ó": { "codepoints": [243], "characters": "\u00F3" }, + "ó": { "codepoints": [243], "characters": "\u00F3" }, + "⊛": { "codepoints": [8859], "characters": "\u229B" }, + "⊚": { "codepoints": [8858], "characters": "\u229A" }, + "ô": { "codepoints": [244], "characters": "\u00F4" }, + "ô": { "codepoints": [244], "characters": "\u00F4" }, + "о": { "codepoints": [1086], "characters": "\u043E" }, + "⊝": { "codepoints": [8861], "characters": "\u229D" }, + "ő": { "codepoints": [337], "characters": "\u0151" }, + "⨸": { "codepoints": [10808], "characters": "\u2A38" }, + "⊙": { "codepoints": [8857], "characters": "\u2299" }, + "⦼": { "codepoints": [10684], "characters": "\u29BC" }, + "œ": { "codepoints": [339], "characters": "\u0153" }, + "⦿": { "codepoints": [10687], "characters": "\u29BF" }, + "𝔬": { "codepoints": [120108], "characters": "\uD835\uDD2C" }, + "˛": { "codepoints": [731], "characters": "\u02DB" }, + "ò": { "codepoints": [242], "characters": "\u00F2" }, + "ò": { "codepoints": [242], "characters": "\u00F2" }, + "⧁": { "codepoints": [10689], "characters": "\u29C1" }, + "⦵": { "codepoints": [10677], "characters": "\u29B5" }, + "Ω": { "codepoints": [937], "characters": "\u03A9" }, + "∮": { "codepoints": [8750], "characters": "\u222E" }, + "↺": { "codepoints": [8634], "characters": "\u21BA" }, + "⦾": { "codepoints": [10686], "characters": "\u29BE" }, + "⦻": { "codepoints": [10683], "characters": "\u29BB" }, + "‾": { "codepoints": [8254], "characters": "\u203E" }, + "⧀": { "codepoints": [10688], "characters": "\u29C0" }, + "ō": { "codepoints": [333], "characters": "\u014D" }, + "ω": { "codepoints": [969], "characters": "\u03C9" }, + "ο": { "codepoints": [959], "characters": "\u03BF" }, + "⦶": { "codepoints": [10678], "characters": "\u29B6" }, + "⊖": { "codepoints": [8854], "characters": "\u2296" }, + "𝕠": { "codepoints": [120160], "characters": "\uD835\uDD60" }, + "⦷": { "codepoints": [10679], "characters": "\u29B7" }, + "⦹": { "codepoints": [10681], "characters": "\u29B9" }, + "⊕": { "codepoints": [8853], "characters": "\u2295" }, + "∨": { "codepoints": [8744], "characters": "\u2228" }, + "↻": { "codepoints": [8635], "characters": "\u21BB" }, + "⩝": { "codepoints": [10845], "characters": "\u2A5D" }, + "ℴ": { "codepoints": [8500], "characters": "\u2134" }, + "ℴ": { "codepoints": [8500], "characters": "\u2134" }, + "ª": { "codepoints": [170], "characters": "\u00AA" }, + "ª": { "codepoints": [170], "characters": "\u00AA" }, + "º": { "codepoints": [186], "characters": "\u00BA" }, + "º": { "codepoints": [186], "characters": "\u00BA" }, + "⊶": { "codepoints": [8886], "characters": "\u22B6" }, + "⩖": { "codepoints": [10838], "characters": "\u2A56" }, + "⩗": { "codepoints": [10839], "characters": "\u2A57" }, + "⩛": { "codepoints": [10843], "characters": "\u2A5B" }, + "ℴ": { "codepoints": [8500], "characters": "\u2134" }, + "ø": { "codepoints": [248], "characters": "\u00F8" }, + "ø": { "codepoints": [248], "characters": "\u00F8" }, + "⊘": { "codepoints": [8856], "characters": "\u2298" }, + "õ": { "codepoints": [245], "characters": "\u00F5" }, + "õ": { "codepoints": [245], "characters": "\u00F5" }, + "⊗": { "codepoints": [8855], "characters": "\u2297" }, + "⨶": { "codepoints": [10806], "characters": "\u2A36" }, + "ö": { "codepoints": [246], "characters": "\u00F6" }, + "ö": { "codepoints": [246], "characters": "\u00F6" }, + "⌽": { "codepoints": [9021], "characters": "\u233D" }, + "∥": { "codepoints": [8741], "characters": "\u2225" }, + "¶": { "codepoints": [182], "characters": "\u00B6" }, + "¶": { "codepoints": [182], "characters": "\u00B6" }, + "∥": { "codepoints": [8741], "characters": "\u2225" }, + "⫳": { "codepoints": [10995], "characters": "\u2AF3" }, + "⫽": { "codepoints": [11005], "characters": "\u2AFD" }, + "∂": { "codepoints": [8706], "characters": "\u2202" }, + "п": { "codepoints": [1087], "characters": "\u043F" }, + "%": { "codepoints": [37], "characters": "\u0025" }, + ".": { "codepoints": [46], "characters": "\u002E" }, + "‰": { "codepoints": [8240], "characters": "\u2030" }, + "⊥": { "codepoints": [8869], "characters": "\u22A5" }, + "‱": { "codepoints": [8241], "characters": "\u2031" }, + "𝔭": { "codepoints": [120109], "characters": "\uD835\uDD2D" }, + "φ": { "codepoints": [966], "characters": "\u03C6" }, + "ϕ": { "codepoints": [981], "characters": "\u03D5" }, + "ℳ": { "codepoints": [8499], "characters": "\u2133" }, + "☎": { "codepoints": [9742], "characters": "\u260E" }, + "π": { "codepoints": [960], "characters": "\u03C0" }, + "⋔": { "codepoints": [8916], "characters": "\u22D4" }, + "ϖ": { "codepoints": [982], "characters": "\u03D6" }, + "ℏ": { "codepoints": [8463], "characters": "\u210F" }, + "ℎ": { "codepoints": [8462], "characters": "\u210E" }, + "ℏ": { "codepoints": [8463], "characters": "\u210F" }, + "+": { "codepoints": [43], "characters": "\u002B" }, + "⨣": { "codepoints": [10787], "characters": "\u2A23" }, + "⊞": { "codepoints": [8862], "characters": "\u229E" }, + "⨢": { "codepoints": [10786], "characters": "\u2A22" }, + "∔": { "codepoints": [8724], "characters": "\u2214" }, + "⨥": { "codepoints": [10789], "characters": "\u2A25" }, + "⩲": { "codepoints": [10866], "characters": "\u2A72" }, + "±": { "codepoints": [177], "characters": "\u00B1" }, + "±": { "codepoints": [177], "characters": "\u00B1" }, + "⨦": { "codepoints": [10790], "characters": "\u2A26" }, + "⨧": { "codepoints": [10791], "characters": "\u2A27" }, + "±": { "codepoints": [177], "characters": "\u00B1" }, + "⨕": { "codepoints": [10773], "characters": "\u2A15" }, + "𝕡": { "codepoints": [120161], "characters": "\uD835\uDD61" }, + "£": { "codepoints": [163], "characters": "\u00A3" }, + "£": { "codepoints": [163], "characters": "\u00A3" }, + "≺": { "codepoints": [8826], "characters": "\u227A" }, + "⪳": { "codepoints": [10931], "characters": "\u2AB3" }, + "⪷": { "codepoints": [10935], "characters": "\u2AB7" }, + "≼": { "codepoints": [8828], "characters": "\u227C" }, + "⪯": { "codepoints": [10927], "characters": "\u2AAF" }, + "≺": { "codepoints": [8826], "characters": "\u227A" }, + "⪷": { "codepoints": [10935], "characters": "\u2AB7" }, + "≼": { "codepoints": [8828], "characters": "\u227C" }, + "⪯": { "codepoints": [10927], "characters": "\u2AAF" }, + "⪹": { "codepoints": [10937], "characters": "\u2AB9" }, + "⪵": { "codepoints": [10933], "characters": "\u2AB5" }, + "⋨": { "codepoints": [8936], "characters": "\u22E8" }, + "≾": { "codepoints": [8830], "characters": "\u227E" }, + "′": { "codepoints": [8242], "characters": "\u2032" }, + "ℙ": { "codepoints": [8473], "characters": "\u2119" }, + "⪵": { "codepoints": [10933], "characters": "\u2AB5" }, + "⪹": { "codepoints": [10937], "characters": "\u2AB9" }, + "⋨": { "codepoints": [8936], "characters": "\u22E8" }, + "∏": { "codepoints": [8719], "characters": "\u220F" }, + "⌮": { "codepoints": [9006], "characters": "\u232E" }, + "⌒": { "codepoints": [8978], "characters": "\u2312" }, + "⌓": { "codepoints": [8979], "characters": "\u2313" }, + "∝": { "codepoints": [8733], "characters": "\u221D" }, + "∝": { "codepoints": [8733], "characters": "\u221D" }, + "≾": { "codepoints": [8830], "characters": "\u227E" }, + "⊰": { "codepoints": [8880], "characters": "\u22B0" }, + "𝓅": { "codepoints": [120005], "characters": "\uD835\uDCC5" }, + "ψ": { "codepoints": [968], "characters": "\u03C8" }, + " ": { "codepoints": [8200], "characters": "\u2008" }, + "𝔮": { "codepoints": [120110], "characters": "\uD835\uDD2E" }, + "⨌": { "codepoints": [10764], "characters": "\u2A0C" }, + "𝕢": { "codepoints": [120162], "characters": "\uD835\uDD62" }, + "⁗": { "codepoints": [8279], "characters": "\u2057" }, + "𝓆": { "codepoints": [120006], "characters": "\uD835\uDCC6" }, + "ℍ": { "codepoints": [8461], "characters": "\u210D" }, + "⨖": { "codepoints": [10774], "characters": "\u2A16" }, + "?": { "codepoints": [63], "characters": "\u003F" }, + "≟": { "codepoints": [8799], "characters": "\u225F" }, + """: { "codepoints": [34], "characters": "\u0022" }, + """: { "codepoints": [34], "characters": "\u0022" }, + "⇛": { "codepoints": [8667], "characters": "\u21DB" }, + "⇒": { "codepoints": [8658], "characters": "\u21D2" }, + "⤜": { "codepoints": [10524], "characters": "\u291C" }, + "⤏": { "codepoints": [10511], "characters": "\u290F" }, + "⥤": { "codepoints": [10596], "characters": "\u2964" }, + "∽̱": { "codepoints": [8765, 817], "characters": "\u223D\u0331" }, + "ŕ": { "codepoints": [341], "characters": "\u0155" }, + "√": { "codepoints": [8730], "characters": "\u221A" }, + "⦳": { "codepoints": [10675], "characters": "\u29B3" }, + "⟩": { "codepoints": [10217], "characters": "\u27E9" }, + "⦒": { "codepoints": [10642], "characters": "\u2992" }, + "⦥": { "codepoints": [10661], "characters": "\u29A5" }, + "⟩": { "codepoints": [10217], "characters": "\u27E9" }, + "»": { "codepoints": [187], "characters": "\u00BB" }, + "»": { "codepoints": [187], "characters": "\u00BB" }, + "→": { "codepoints": [8594], "characters": "\u2192" }, + "⥵": { "codepoints": [10613], "characters": "\u2975" }, + "⇥": { "codepoints": [8677], "characters": "\u21E5" }, + "⤠": { "codepoints": [10528], "characters": "\u2920" }, + "⤳": { "codepoints": [10547], "characters": "\u2933" }, + "⤞": { "codepoints": [10526], "characters": "\u291E" }, + "↪": { "codepoints": [8618], "characters": "\u21AA" }, + "↬": { "codepoints": [8620], "characters": "\u21AC" }, + "⥅": { "codepoints": [10565], "characters": "\u2945" }, + "⥴": { "codepoints": [10612], "characters": "\u2974" }, + "↣": { "codepoints": [8611], "characters": "\u21A3" }, + "↝": { "codepoints": [8605], "characters": "\u219D" }, + "⤚": { "codepoints": [10522], "characters": "\u291A" }, + "∶": { "codepoints": [8758], "characters": "\u2236" }, + "ℚ": { "codepoints": [8474], "characters": "\u211A" }, + "⤍": { "codepoints": [10509], "characters": "\u290D" }, + "❳": { "codepoints": [10099], "characters": "\u2773" }, + "}": { "codepoints": [125], "characters": "\u007D" }, + "]": { "codepoints": [93], "characters": "\u005D" }, + "⦌": { "codepoints": [10636], "characters": "\u298C" }, + "⦎": { "codepoints": [10638], "characters": "\u298E" }, + "⦐": { "codepoints": [10640], "characters": "\u2990" }, + "ř": { "codepoints": [345], "characters": "\u0159" }, + "ŗ": { "codepoints": [343], "characters": "\u0157" }, + "⌉": { "codepoints": [8969], "characters": "\u2309" }, + "}": { "codepoints": [125], "characters": "\u007D" }, + "р": { "codepoints": [1088], "characters": "\u0440" }, + "⤷": { "codepoints": [10551], "characters": "\u2937" }, + "⥩": { "codepoints": [10601], "characters": "\u2969" }, + "”": { "codepoints": [8221], "characters": "\u201D" }, + "”": { "codepoints": [8221], "characters": "\u201D" }, + "↳": { "codepoints": [8627], "characters": "\u21B3" }, + "ℜ": { "codepoints": [8476], "characters": "\u211C" }, + "ℛ": { "codepoints": [8475], "characters": "\u211B" }, + "ℜ": { "codepoints": [8476], "characters": "\u211C" }, + "ℝ": { "codepoints": [8477], "characters": "\u211D" }, + "▭": { "codepoints": [9645], "characters": "\u25AD" }, + "®": { "codepoints": [174], "characters": "\u00AE" }, + "®": { "codepoints": [174], "characters": "\u00AE" }, + "⥽": { "codepoints": [10621], "characters": "\u297D" }, + "⌋": { "codepoints": [8971], "characters": "\u230B" }, + "𝔯": { "codepoints": [120111], "characters": "\uD835\uDD2F" }, + "⇁": { "codepoints": [8641], "characters": "\u21C1" }, + "⇀": { "codepoints": [8640], "characters": "\u21C0" }, + "⥬": { "codepoints": [10604], "characters": "\u296C" }, + "ρ": { "codepoints": [961], "characters": "\u03C1" }, + "ϱ": { "codepoints": [1009], "characters": "\u03F1" }, + "→": { "codepoints": [8594], "characters": "\u2192" }, + "↣": { "codepoints": [8611], "characters": "\u21A3" }, + "⇁": { "codepoints": [8641], "characters": "\u21C1" }, + "⇀": { "codepoints": [8640], "characters": "\u21C0" }, + "⇄": { "codepoints": [8644], "characters": "\u21C4" }, + "⇌": { "codepoints": [8652], "characters": "\u21CC" }, + "⇉": { "codepoints": [8649], "characters": "\u21C9" }, + "↝": { "codepoints": [8605], "characters": "\u219D" }, + "⋌": { "codepoints": [8908], "characters": "\u22CC" }, + "˚": { "codepoints": [730], "characters": "\u02DA" }, + "≓": { "codepoints": [8787], "characters": "\u2253" }, + "⇄": { "codepoints": [8644], "characters": "\u21C4" }, + "⇌": { "codepoints": [8652], "characters": "\u21CC" }, + "‏": { "codepoints": [8207], "characters": "\u200F" }, + "⎱": { "codepoints": [9137], "characters": "\u23B1" }, + "⎱": { "codepoints": [9137], "characters": "\u23B1" }, + "⫮": { "codepoints": [10990], "characters": "\u2AEE" }, + "⟭": { "codepoints": [10221], "characters": "\u27ED" }, + "⇾": { "codepoints": [8702], "characters": "\u21FE" }, + "⟧": { "codepoints": [10215], "characters": "\u27E7" }, + "⦆": { "codepoints": [10630], "characters": "\u2986" }, + "𝕣": { "codepoints": [120163], "characters": "\uD835\uDD63" }, + "⨮": { "codepoints": [10798], "characters": "\u2A2E" }, + "⨵": { "codepoints": [10805], "characters": "\u2A35" }, + ")": { "codepoints": [41], "characters": "\u0029" }, + "⦔": { "codepoints": [10644], "characters": "\u2994" }, + "⨒": { "codepoints": [10770], "characters": "\u2A12" }, + "⇉": { "codepoints": [8649], "characters": "\u21C9" }, + "›": { "codepoints": [8250], "characters": "\u203A" }, + "𝓇": { "codepoints": [120007], "characters": "\uD835\uDCC7" }, + "↱": { "codepoints": [8625], "characters": "\u21B1" }, + "]": { "codepoints": [93], "characters": "\u005D" }, + "’": { "codepoints": [8217], "characters": "\u2019" }, + "’": { "codepoints": [8217], "characters": "\u2019" }, + "⋌": { "codepoints": [8908], "characters": "\u22CC" }, + "⋊": { "codepoints": [8906], "characters": "\u22CA" }, + "▹": { "codepoints": [9657], "characters": "\u25B9" }, + "⊵": { "codepoints": [8885], "characters": "\u22B5" }, + "▸": { "codepoints": [9656], "characters": "\u25B8" }, + "⧎": { "codepoints": [10702], "characters": "\u29CE" }, + "⥨": { "codepoints": [10600], "characters": "\u2968" }, + "℞": { "codepoints": [8478], "characters": "\u211E" }, + "ś": { "codepoints": [347], "characters": "\u015B" }, + "‚": { "codepoints": [8218], "characters": "\u201A" }, + "≻": { "codepoints": [8827], "characters": "\u227B" }, + "⪴": { "codepoints": [10932], "characters": "\u2AB4" }, + "⪸": { "codepoints": [10936], "characters": "\u2AB8" }, + "š": { "codepoints": [353], "characters": "\u0161" }, + "≽": { "codepoints": [8829], "characters": "\u227D" }, + "⪰": { "codepoints": [10928], "characters": "\u2AB0" }, + "ş": { "codepoints": [351], "characters": "\u015F" }, + "ŝ": { "codepoints": [349], "characters": "\u015D" }, + "⪶": { "codepoints": [10934], "characters": "\u2AB6" }, + "⪺": { "codepoints": [10938], "characters": "\u2ABA" }, + "⋩": { "codepoints": [8937], "characters": "\u22E9" }, + "⨓": { "codepoints": [10771], "characters": "\u2A13" }, + "≿": { "codepoints": [8831], "characters": "\u227F" }, + "с": { "codepoints": [1089], "characters": "\u0441" }, + "⋅": { "codepoints": [8901], "characters": "\u22C5" }, + "⊡": { "codepoints": [8865], "characters": "\u22A1" }, + "⩦": { "codepoints": [10854], "characters": "\u2A66" }, + "⇘": { "codepoints": [8664], "characters": "\u21D8" }, + "⤥": { "codepoints": [10533], "characters": "\u2925" }, + "↘": { "codepoints": [8600], "characters": "\u2198" }, + "↘": { "codepoints": [8600], "characters": "\u2198" }, + "§": { "codepoints": [167], "characters": "\u00A7" }, + "§": { "codepoints": [167], "characters": "\u00A7" }, + ";": { "codepoints": [59], "characters": "\u003B" }, + "⤩": { "codepoints": [10537], "characters": "\u2929" }, + "∖": { "codepoints": [8726], "characters": "\u2216" }, + "∖": { "codepoints": [8726], "characters": "\u2216" }, + "✶": { "codepoints": [10038], "characters": "\u2736" }, + "𝔰": { "codepoints": [120112], "characters": "\uD835\uDD30" }, + "⌢": { "codepoints": [8994], "characters": "\u2322" }, + "♯": { "codepoints": [9839], "characters": "\u266F" }, + "щ": { "codepoints": [1097], "characters": "\u0449" }, + "ш": { "codepoints": [1096], "characters": "\u0448" }, + "∣": { "codepoints": [8739], "characters": "\u2223" }, + "∥": { "codepoints": [8741], "characters": "\u2225" }, + "­": { "codepoints": [173], "characters": "\u00AD" }, + "­": { "codepoints": [173], "characters": "\u00AD" }, + "σ": { "codepoints": [963], "characters": "\u03C3" }, + "ς": { "codepoints": [962], "characters": "\u03C2" }, + "ς": { "codepoints": [962], "characters": "\u03C2" }, + "∼": { "codepoints": [8764], "characters": "\u223C" }, + "⩪": { "codepoints": [10858], "characters": "\u2A6A" }, + "≃": { "codepoints": [8771], "characters": "\u2243" }, + "≃": { "codepoints": [8771], "characters": "\u2243" }, + "⪞": { "codepoints": [10910], "characters": "\u2A9E" }, + "⪠": { "codepoints": [10912], "characters": "\u2AA0" }, + "⪝": { "codepoints": [10909], "characters": "\u2A9D" }, + "⪟": { "codepoints": [10911], "characters": "\u2A9F" }, + "≆": { "codepoints": [8774], "characters": "\u2246" }, + "⨤": { "codepoints": [10788], "characters": "\u2A24" }, + "⥲": { "codepoints": [10610], "characters": "\u2972" }, + "←": { "codepoints": [8592], "characters": "\u2190" }, + "∖": { "codepoints": [8726], "characters": "\u2216" }, + "⨳": { "codepoints": [10803], "characters": "\u2A33" }, + "⧤": { "codepoints": [10724], "characters": "\u29E4" }, + "∣": { "codepoints": [8739], "characters": "\u2223" }, + "⌣": { "codepoints": [8995], "characters": "\u2323" }, + "⪪": { "codepoints": [10922], "characters": "\u2AAA" }, + "⪬": { "codepoints": [10924], "characters": "\u2AAC" }, + "⪬︀": { "codepoints": [10924, 65024], "characters": "\u2AAC\uFE00" }, + "ь": { "codepoints": [1100], "characters": "\u044C" }, + "/": { "codepoints": [47], "characters": "\u002F" }, + "⧄": { "codepoints": [10692], "characters": "\u29C4" }, + "⌿": { "codepoints": [9023], "characters": "\u233F" }, + "𝕤": { "codepoints": [120164], "characters": "\uD835\uDD64" }, + "♠": { "codepoints": [9824], "characters": "\u2660" }, + "♠": { "codepoints": [9824], "characters": "\u2660" }, + "∥": { "codepoints": [8741], "characters": "\u2225" }, + "⊓": { "codepoints": [8851], "characters": "\u2293" }, + "⊓︀": { "codepoints": [8851, 65024], "characters": "\u2293\uFE00" }, + "⊔": { "codepoints": [8852], "characters": "\u2294" }, + "⊔︀": { "codepoints": [8852, 65024], "characters": "\u2294\uFE00" }, + "⊏": { "codepoints": [8847], "characters": "\u228F" }, + "⊑": { "codepoints": [8849], "characters": "\u2291" }, + "⊏": { "codepoints": [8847], "characters": "\u228F" }, + "⊑": { "codepoints": [8849], "characters": "\u2291" }, + "⊐": { "codepoints": [8848], "characters": "\u2290" }, + "⊒": { "codepoints": [8850], "characters": "\u2292" }, + "⊐": { "codepoints": [8848], "characters": "\u2290" }, + "⊒": { "codepoints": [8850], "characters": "\u2292" }, + "□": { "codepoints": [9633], "characters": "\u25A1" }, + "□": { "codepoints": [9633], "characters": "\u25A1" }, + "▪": { "codepoints": [9642], "characters": "\u25AA" }, + "▪": { "codepoints": [9642], "characters": "\u25AA" }, + "→": { "codepoints": [8594], "characters": "\u2192" }, + "𝓈": { "codepoints": [120008], "characters": "\uD835\uDCC8" }, + "∖": { "codepoints": [8726], "characters": "\u2216" }, + "⌣": { "codepoints": [8995], "characters": "\u2323" }, + "⋆": { "codepoints": [8902], "characters": "\u22C6" }, + "☆": { "codepoints": [9734], "characters": "\u2606" }, + "★": { "codepoints": [9733], "characters": "\u2605" }, + "ϵ": { "codepoints": [1013], "characters": "\u03F5" }, + "ϕ": { "codepoints": [981], "characters": "\u03D5" }, + "¯": { "codepoints": [175], "characters": "\u00AF" }, + "⊂": { "codepoints": [8834], "characters": "\u2282" }, + "⫅": { "codepoints": [10949], "characters": "\u2AC5" }, + "⪽": { "codepoints": [10941], "characters": "\u2ABD" }, + "⊆": { "codepoints": [8838], "characters": "\u2286" }, + "⫃": { "codepoints": [10947], "characters": "\u2AC3" }, + "⫁": { "codepoints": [10945], "characters": "\u2AC1" }, + "⫋": { "codepoints": [10955], "characters": "\u2ACB" }, + "⊊": { "codepoints": [8842], "characters": "\u228A" }, + "⪿": { "codepoints": [10943], "characters": "\u2ABF" }, + "⥹": { "codepoints": [10617], "characters": "\u2979" }, + "⊂": { "codepoints": [8834], "characters": "\u2282" }, + "⊆": { "codepoints": [8838], "characters": "\u2286" }, + "⫅": { "codepoints": [10949], "characters": "\u2AC5" }, + "⊊": { "codepoints": [8842], "characters": "\u228A" }, + "⫋": { "codepoints": [10955], "characters": "\u2ACB" }, + "⫇": { "codepoints": [10951], "characters": "\u2AC7" }, + "⫕": { "codepoints": [10965], "characters": "\u2AD5" }, + "⫓": { "codepoints": [10963], "characters": "\u2AD3" }, + "≻": { "codepoints": [8827], "characters": "\u227B" }, + "⪸": { "codepoints": [10936], "characters": "\u2AB8" }, + "≽": { "codepoints": [8829], "characters": "\u227D" }, + "⪰": { "codepoints": [10928], "characters": "\u2AB0" }, + "⪺": { "codepoints": [10938], "characters": "\u2ABA" }, + "⪶": { "codepoints": [10934], "characters": "\u2AB6" }, + "⋩": { "codepoints": [8937], "characters": "\u22E9" }, + "≿": { "codepoints": [8831], "characters": "\u227F" }, + "∑": { "codepoints": [8721], "characters": "\u2211" }, + "♪": { "codepoints": [9834], "characters": "\u266A" }, + "¹": { "codepoints": [185], "characters": "\u00B9" }, + "¹": { "codepoints": [185], "characters": "\u00B9" }, + "²": { "codepoints": [178], "characters": "\u00B2" }, + "²": { "codepoints": [178], "characters": "\u00B2" }, + "³": { "codepoints": [179], "characters": "\u00B3" }, + "³": { "codepoints": [179], "characters": "\u00B3" }, + "⊃": { "codepoints": [8835], "characters": "\u2283" }, + "⫆": { "codepoints": [10950], "characters": "\u2AC6" }, + "⪾": { "codepoints": [10942], "characters": "\u2ABE" }, + "⫘": { "codepoints": [10968], "characters": "\u2AD8" }, + "⊇": { "codepoints": [8839], "characters": "\u2287" }, + "⫄": { "codepoints": [10948], "characters": "\u2AC4" }, + "⟉": { "codepoints": [10185], "characters": "\u27C9" }, + "⫗": { "codepoints": [10967], "characters": "\u2AD7" }, + "⥻": { "codepoints": [10619], "characters": "\u297B" }, + "⫂": { "codepoints": [10946], "characters": "\u2AC2" }, + "⫌": { "codepoints": [10956], "characters": "\u2ACC" }, + "⊋": { "codepoints": [8843], "characters": "\u228B" }, + "⫀": { "codepoints": [10944], "characters": "\u2AC0" }, + "⊃": { "codepoints": [8835], "characters": "\u2283" }, + "⊇": { "codepoints": [8839], "characters": "\u2287" }, + "⫆": { "codepoints": [10950], "characters": "\u2AC6" }, + "⊋": { "codepoints": [8843], "characters": "\u228B" }, + "⫌": { "codepoints": [10956], "characters": "\u2ACC" }, + "⫈": { "codepoints": [10952], "characters": "\u2AC8" }, + "⫔": { "codepoints": [10964], "characters": "\u2AD4" }, + "⫖": { "codepoints": [10966], "characters": "\u2AD6" }, + "⇙": { "codepoints": [8665], "characters": "\u21D9" }, + "⤦": { "codepoints": [10534], "characters": "\u2926" }, + "↙": { "codepoints": [8601], "characters": "\u2199" }, + "↙": { "codepoints": [8601], "characters": "\u2199" }, + "⤪": { "codepoints": [10538], "characters": "\u292A" }, + "ß": { "codepoints": [223], "characters": "\u00DF" }, + "ß": { "codepoints": [223], "characters": "\u00DF" }, + "⌖": { "codepoints": [8982], "characters": "\u2316" }, + "τ": { "codepoints": [964], "characters": "\u03C4" }, + "⎴": { "codepoints": [9140], "characters": "\u23B4" }, + "ť": { "codepoints": [357], "characters": "\u0165" }, + "ţ": { "codepoints": [355], "characters": "\u0163" }, + "т": { "codepoints": [1090], "characters": "\u0442" }, + "⃛": { "codepoints": [8411], "characters": "\u20DB" }, + "⌕": { "codepoints": [8981], "characters": "\u2315" }, + "𝔱": { "codepoints": [120113], "characters": "\uD835\uDD31" }, + "∴": { "codepoints": [8756], "characters": "\u2234" }, + "∴": { "codepoints": [8756], "characters": "\u2234" }, + "θ": { "codepoints": [952], "characters": "\u03B8" }, + "ϑ": { "codepoints": [977], "characters": "\u03D1" }, + "ϑ": { "codepoints": [977], "characters": "\u03D1" }, + "≈": { "codepoints": [8776], "characters": "\u2248" }, + "∼": { "codepoints": [8764], "characters": "\u223C" }, + " ": { "codepoints": [8201], "characters": "\u2009" }, + "≈": { "codepoints": [8776], "characters": "\u2248" }, + "∼": { "codepoints": [8764], "characters": "\u223C" }, + "þ": { "codepoints": [254], "characters": "\u00FE" }, + "þ": { "codepoints": [254], "characters": "\u00FE" }, + "˜": { "codepoints": [732], "characters": "\u02DC" }, + "×": { "codepoints": [215], "characters": "\u00D7" }, + "×": { "codepoints": [215], "characters": "\u00D7" }, + "⊠": { "codepoints": [8864], "characters": "\u22A0" }, + "⨱": { "codepoints": [10801], "characters": "\u2A31" }, + "⨰": { "codepoints": [10800], "characters": "\u2A30" }, + "∭": { "codepoints": [8749], "characters": "\u222D" }, + "⤨": { "codepoints": [10536], "characters": "\u2928" }, + "⊤": { "codepoints": [8868], "characters": "\u22A4" }, + "⌶": { "codepoints": [9014], "characters": "\u2336" }, + "⫱": { "codepoints": [10993], "characters": "\u2AF1" }, + "𝕥": { "codepoints": [120165], "characters": "\uD835\uDD65" }, + "⫚": { "codepoints": [10970], "characters": "\u2ADA" }, + "⤩": { "codepoints": [10537], "characters": "\u2929" }, + "‴": { "codepoints": [8244], "characters": "\u2034" }, + "™": { "codepoints": [8482], "characters": "\u2122" }, + "▵": { "codepoints": [9653], "characters": "\u25B5" }, + "▿": { "codepoints": [9663], "characters": "\u25BF" }, + "◃": { "codepoints": [9667], "characters": "\u25C3" }, + "⊴": { "codepoints": [8884], "characters": "\u22B4" }, + "≜": { "codepoints": [8796], "characters": "\u225C" }, + "▹": { "codepoints": [9657], "characters": "\u25B9" }, + "⊵": { "codepoints": [8885], "characters": "\u22B5" }, + "◬": { "codepoints": [9708], "characters": "\u25EC" }, + "≜": { "codepoints": [8796], "characters": "\u225C" }, + "⨺": { "codepoints": [10810], "characters": "\u2A3A" }, + "⨹": { "codepoints": [10809], "characters": "\u2A39" }, + "⧍": { "codepoints": [10701], "characters": "\u29CD" }, + "⨻": { "codepoints": [10811], "characters": "\u2A3B" }, + "⏢": { "codepoints": [9186], "characters": "\u23E2" }, + "𝓉": { "codepoints": [120009], "characters": "\uD835\uDCC9" }, + "ц": { "codepoints": [1094], "characters": "\u0446" }, + "ћ": { "codepoints": [1115], "characters": "\u045B" }, + "ŧ": { "codepoints": [359], "characters": "\u0167" }, + "≬": { "codepoints": [8812], "characters": "\u226C" }, + "↞": { "codepoints": [8606], "characters": "\u219E" }, + "↠": { "codepoints": [8608], "characters": "\u21A0" }, + "⇑": { "codepoints": [8657], "characters": "\u21D1" }, + "⥣": { "codepoints": [10595], "characters": "\u2963" }, + "ú": { "codepoints": [250], "characters": "\u00FA" }, + "ú": { "codepoints": [250], "characters": "\u00FA" }, + "↑": { "codepoints": [8593], "characters": "\u2191" }, + "ў": { "codepoints": [1118], "characters": "\u045E" }, + "ŭ": { "codepoints": [365], "characters": "\u016D" }, + "û": { "codepoints": [251], "characters": "\u00FB" }, + "û": { "codepoints": [251], "characters": "\u00FB" }, + "у": { "codepoints": [1091], "characters": "\u0443" }, + "⇅": { "codepoints": [8645], "characters": "\u21C5" }, + "ű": { "codepoints": [369], "characters": "\u0171" }, + "⥮": { "codepoints": [10606], "characters": "\u296E" }, + "⥾": { "codepoints": [10622], "characters": "\u297E" }, + "𝔲": { "codepoints": [120114], "characters": "\uD835\uDD32" }, + "ù": { "codepoints": [249], "characters": "\u00F9" }, + "ù": { "codepoints": [249], "characters": "\u00F9" }, + "↿": { "codepoints": [8639], "characters": "\u21BF" }, + "↾": { "codepoints": [8638], "characters": "\u21BE" }, + "▀": { "codepoints": [9600], "characters": "\u2580" }, + "⌜": { "codepoints": [8988], "characters": "\u231C" }, + "⌜": { "codepoints": [8988], "characters": "\u231C" }, + "⌏": { "codepoints": [8975], "characters": "\u230F" }, + "◸": { "codepoints": [9720], "characters": "\u25F8" }, + "ū": { "codepoints": [363], "characters": "\u016B" }, + "¨": { "codepoints": [168], "characters": "\u00A8" }, + "¨": { "codepoints": [168], "characters": "\u00A8" }, + "ų": { "codepoints": [371], "characters": "\u0173" }, + "𝕦": { "codepoints": [120166], "characters": "\uD835\uDD66" }, + "↑": { "codepoints": [8593], "characters": "\u2191" }, + "↕": { "codepoints": [8597], "characters": "\u2195" }, + "↿": { "codepoints": [8639], "characters": "\u21BF" }, + "↾": { "codepoints": [8638], "characters": "\u21BE" }, + "⊎": { "codepoints": [8846], "characters": "\u228E" }, + "υ": { "codepoints": [965], "characters": "\u03C5" }, + "ϒ": { "codepoints": [978], "characters": "\u03D2" }, + "υ": { "codepoints": [965], "characters": "\u03C5" }, + "⇈": { "codepoints": [8648], "characters": "\u21C8" }, + "⌝": { "codepoints": [8989], "characters": "\u231D" }, + "⌝": { "codepoints": [8989], "characters": "\u231D" }, + "⌎": { "codepoints": [8974], "characters": "\u230E" }, + "ů": { "codepoints": [367], "characters": "\u016F" }, + "◹": { "codepoints": [9721], "characters": "\u25F9" }, + "𝓊": { "codepoints": [120010], "characters": "\uD835\uDCCA" }, + "⋰": { "codepoints": [8944], "characters": "\u22F0" }, + "ũ": { "codepoints": [361], "characters": "\u0169" }, + "▵": { "codepoints": [9653], "characters": "\u25B5" }, + "▴": { "codepoints": [9652], "characters": "\u25B4" }, + "⇈": { "codepoints": [8648], "characters": "\u21C8" }, + "ü": { "codepoints": [252], "characters": "\u00FC" }, + "ü": { "codepoints": [252], "characters": "\u00FC" }, + "⦧": { "codepoints": [10663], "characters": "\u29A7" }, + "⇕": { "codepoints": [8661], "characters": "\u21D5" }, + "⫨": { "codepoints": [10984], "characters": "\u2AE8" }, + "⫩": { "codepoints": [10985], "characters": "\u2AE9" }, + "⊨": { "codepoints": [8872], "characters": "\u22A8" }, + "⦜": { "codepoints": [10652], "characters": "\u299C" }, + "ϵ": { "codepoints": [1013], "characters": "\u03F5" }, + "ϰ": { "codepoints": [1008], "characters": "\u03F0" }, + "∅": { "codepoints": [8709], "characters": "\u2205" }, + "ϕ": { "codepoints": [981], "characters": "\u03D5" }, + "ϖ": { "codepoints": [982], "characters": "\u03D6" }, + "∝": { "codepoints": [8733], "characters": "\u221D" }, + "↕": { "codepoints": [8597], "characters": "\u2195" }, + "ϱ": { "codepoints": [1009], "characters": "\u03F1" }, + "ς": { "codepoints": [962], "characters": "\u03C2" }, + "⊊︀": { "codepoints": [8842, 65024], "characters": "\u228A\uFE00" }, + "⫋︀": { "codepoints": [10955, 65024], "characters": "\u2ACB\uFE00" }, + "⊋︀": { "codepoints": [8843, 65024], "characters": "\u228B\uFE00" }, + "⫌︀": { "codepoints": [10956, 65024], "characters": "\u2ACC\uFE00" }, + "ϑ": { "codepoints": [977], "characters": "\u03D1" }, + "⊲": { "codepoints": [8882], "characters": "\u22B2" }, + "⊳": { "codepoints": [8883], "characters": "\u22B3" }, + "в": { "codepoints": [1074], "characters": "\u0432" }, + "⊢": { "codepoints": [8866], "characters": "\u22A2" }, + "∨": { "codepoints": [8744], "characters": "\u2228" }, + "⊻": { "codepoints": [8891], "characters": "\u22BB" }, + "≚": { "codepoints": [8794], "characters": "\u225A" }, + "⋮": { "codepoints": [8942], "characters": "\u22EE" }, + "|": { "codepoints": [124], "characters": "\u007C" }, + "|": { "codepoints": [124], "characters": "\u007C" }, + "𝔳": { "codepoints": [120115], "characters": "\uD835\uDD33" }, + "⊲": { "codepoints": [8882], "characters": "\u22B2" }, + "⊂⃒": { "codepoints": [8834, 8402], "characters": "\u2282\u20D2" }, + "⊃⃒": { "codepoints": [8835, 8402], "characters": "\u2283\u20D2" }, + "𝕧": { "codepoints": [120167], "characters": "\uD835\uDD67" }, + "∝": { "codepoints": [8733], "characters": "\u221D" }, + "⊳": { "codepoints": [8883], "characters": "\u22B3" }, + "𝓋": { "codepoints": [120011], "characters": "\uD835\uDCCB" }, + "⫋︀": { "codepoints": [10955, 65024], "characters": "\u2ACB\uFE00" }, + "⊊︀": { "codepoints": [8842, 65024], "characters": "\u228A\uFE00" }, + "⫌︀": { "codepoints": [10956, 65024], "characters": "\u2ACC\uFE00" }, + "⊋︀": { "codepoints": [8843, 65024], "characters": "\u228B\uFE00" }, + "⦚": { "codepoints": [10650], "characters": "\u299A" }, + "ŵ": { "codepoints": [373], "characters": "\u0175" }, + "⩟": { "codepoints": [10847], "characters": "\u2A5F" }, + "∧": { "codepoints": [8743], "characters": "\u2227" }, + "≙": { "codepoints": [8793], "characters": "\u2259" }, + "℘": { "codepoints": [8472], "characters": "\u2118" }, + "𝔴": { "codepoints": [120116], "characters": "\uD835\uDD34" }, + "𝕨": { "codepoints": [120168], "characters": "\uD835\uDD68" }, + "℘": { "codepoints": [8472], "characters": "\u2118" }, + "≀": { "codepoints": [8768], "characters": "\u2240" }, + "≀": { "codepoints": [8768], "characters": "\u2240" }, + "𝓌": { "codepoints": [120012], "characters": "\uD835\uDCCC" }, + "⋂": { "codepoints": [8898], "characters": "\u22C2" }, + "◯": { "codepoints": [9711], "characters": "\u25EF" }, + "⋃": { "codepoints": [8899], "characters": "\u22C3" }, + "▽": { "codepoints": [9661], "characters": "\u25BD" }, + "𝔵": { "codepoints": [120117], "characters": "\uD835\uDD35" }, + "⟺": { "codepoints": [10234], "characters": "\u27FA" }, + "⟷": { "codepoints": [10231], "characters": "\u27F7" }, + "ξ": { "codepoints": [958], "characters": "\u03BE" }, + "⟸": { "codepoints": [10232], "characters": "\u27F8" }, + "⟵": { "codepoints": [10229], "characters": "\u27F5" }, + "⟼": { "codepoints": [10236], "characters": "\u27FC" }, + "⋻": { "codepoints": [8955], "characters": "\u22FB" }, + "⨀": { "codepoints": [10752], "characters": "\u2A00" }, + "𝕩": { "codepoints": [120169], "characters": "\uD835\uDD69" }, + "⨁": { "codepoints": [10753], "characters": "\u2A01" }, + "⨂": { "codepoints": [10754], "characters": "\u2A02" }, + "⟹": { "codepoints": [10233], "characters": "\u27F9" }, + "⟶": { "codepoints": [10230], "characters": "\u27F6" }, + "𝓍": { "codepoints": [120013], "characters": "\uD835\uDCCD" }, + "⨆": { "codepoints": [10758], "characters": "\u2A06" }, + "⨄": { "codepoints": [10756], "characters": "\u2A04" }, + "△": { "codepoints": [9651], "characters": "\u25B3" }, + "⋁": { "codepoints": [8897], "characters": "\u22C1" }, + "⋀": { "codepoints": [8896], "characters": "\u22C0" }, + "ý": { "codepoints": [253], "characters": "\u00FD" }, + "ý": { "codepoints": [253], "characters": "\u00FD" }, + "я": { "codepoints": [1103], "characters": "\u044F" }, + "ŷ": { "codepoints": [375], "characters": "\u0177" }, + "ы": { "codepoints": [1099], "characters": "\u044B" }, + "¥": { "codepoints": [165], "characters": "\u00A5" }, + "¥": { "codepoints": [165], "characters": "\u00A5" }, + "𝔶": { "codepoints": [120118], "characters": "\uD835\uDD36" }, + "ї": { "codepoints": [1111], "characters": "\u0457" }, + "𝕪": { "codepoints": [120170], "characters": "\uD835\uDD6A" }, + "𝓎": { "codepoints": [120014], "characters": "\uD835\uDCCE" }, + "ю": { "codepoints": [1102], "characters": "\u044E" }, + "ÿ": { "codepoints": [255], "characters": "\u00FF" }, + "ÿ": { "codepoints": [255], "characters": "\u00FF" }, + "ź": { "codepoints": [378], "characters": "\u017A" }, + "ž": { "codepoints": [382], "characters": "\u017E" }, + "з": { "codepoints": [1079], "characters": "\u0437" }, + "ż": { "codepoints": [380], "characters": "\u017C" }, + "ℨ": { "codepoints": [8488], "characters": "\u2128" }, + "ζ": { "codepoints": [950], "characters": "\u03B6" }, + "𝔷": { "codepoints": [120119], "characters": "\uD835\uDD37" }, + "ж": { "codepoints": [1078], "characters": "\u0436" }, + "⇝": { "codepoints": [8669], "characters": "\u21DD" }, + "𝕫": { "codepoints": [120171], "characters": "\uD835\uDD6B" }, + "𝓏": { "codepoints": [120015], "characters": "\uD835\uDCCF" }, + "‍": { "codepoints": [8205], "characters": "\u200D" }, + "‌": { "codepoints": [8204], "characters": "\u200C" } +} diff --git a/src/reason-parser/vendor/omd/tools/gen_entities.ml b/src/reason-parser/vendor/omd/tools/gen_entities.ml new file mode 100644 index 000000000..5035ae65f --- /dev/null +++ b/src/reason-parser/vendor/omd/tools/gen_entities.ml @@ -0,0 +1,28 @@ +let f s = + Scanf.sscanf s " \"&%s@;\": { %_S: [%s@], %_S: \"%_s@\" }" + (fun s nums -> + s, List.map (fun s -> int_of_string (String.trim s)) (String.split_on_char ',' nums)) + +let main ic = + let rec loop () = + match input_line ic with + | s -> + begin match f s with + | name, codepoints -> + Printf.printf " | %S -> [" name; + List.iteri (fun i cp -> if i > 0 then print_string "; "; Printf.printf "Uchar.of_int %d" cp) codepoints; + Printf.printf "]\n" + | exception _ -> + () + end; + loop () + | exception End_of_file -> + Printf.printf " | _ -> []\n%!" + in + Printf.printf "let f = function\n"; + loop () + +let () = + let ic = open_in Sys.argv.(1) in + main ic; + close_in ic