diff --git a/README.md b/README.md new file mode 100644 index 0000000..dca8956 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +build for rpi: + + zig build -Dtarget=aarch64-linux-musl -Ddriver=fbev -Drelease-safe -Dstrip + +otherwise just `zig build` on dev host diff --git a/build.zig b/build.zig index aee9674..f6ea0ed 100644 --- a/build.zig +++ b/build.zig @@ -1,34 +1,283 @@ const std = @import("std"); +const nifbuild = @import("lib/nif/build.zig"); pub fn build(b: *std.build.Builder) void { - // Standard target options allows the person running `zig build` to choose - // what target to build for. Here we do not override the defaults, which - // means any target is allowed, and the default is native. Other options - // for restricting supported target set are available. - const target = b.standardTargetOptions(.{}); + b.use_stage1 = true; - // Standard release options allow the person running `zig build` to select - // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. + const target = b.standardTargetOptions(.{}); const mode = b.standardReleaseOptions(); + const strip = b.option(bool, "strip", "strip output binary; default: false") orelse false; + const drv = b.option(DriverTarget, "driver", "display and input drivers combo; default: sdl2") orelse .sdl2; + const disp_horiz = b.option(u32, "horiz", "display horizontal pixels count; default: 800") orelse 800; + const disp_vert = b.option(u32, "vert", "display vertical pixels count; default: 480") orelse 480; + + // gui build + const ngui = b.addExecutable("ngui", "src/ngui.zig"); + ngui.setTarget(target); + ngui.setBuildMode(mode); + ngui.pie = true; + ngui.strip = strip; + + ngui.addIncludePath("lib"); + ngui.addIncludePath("src/ui/c"); + ngui.linkLibC(); - const exe = b.addExecutable("ngui", "src/main.zig"); - exe.setTarget(target); - exe.setBuildMode(mode); - exe.install(); + const lvgl_flags = &.{ + "-std=c11", + "-fstack-protector", + "-Wall", + "-Wextra", + "-Wformat", + "-Wformat-security", + "-Wundef", + }; + ngui.addCSourceFiles(lvgl_generic_src, lvgl_flags); - const run_cmd = exe.run(); - run_cmd.step.dependOn(b.getInstallStep()); - if (b.args) |args| { - run_cmd.addArgs(args); + const ngui_cflags: []const []const u8 = &.{ + "-std=c11", + "-Wall", + "-Wextra", + "-Wshadow", + "-Wundef", + "-Wunused-parameter", + "-Werror", + }; + ngui.addCSourceFiles(&.{ + "src/ui/c/ui.c", + "src/ui/c/lv_font_courierprimecode_14.c", + //"src/ui/c/lv_font_courierprimecode_16.c", + "src/ui/c/lv_font_courierprimecode_24.c", + }, ngui_cflags); + + ngui.defineCMacroRaw(b.fmt("NM_DISP_HOR={}", .{disp_horiz})); + ngui.defineCMacroRaw(b.fmt("NM_DISP_VER={}", .{disp_vert})); + ngui.defineCMacro("LV_CONF_INCLUDE_SIMPLE", null); + ngui.defineCMacro("LV_TICK_CUSTOM", "1"); + ngui.defineCMacro("LV_TICK_CUSTOM_INCLUDE", "\"ui.h\""); + ngui.defineCMacro("LV_TICK_CUSTOM_SYS_TIME_EXPR", "(nm_get_curr_tick())"); + switch (drv) { + .sdl2 => { + ngui.addCSourceFiles(lvgl_sdl2_src, lvgl_flags); + ngui.addCSourceFile("src/ui/c/drv_sdl2.c", ngui_cflags); + ngui.defineCMacro("NM_DRV_SDL2", null); + ngui.defineCMacro("USE_SDL", null); + ngui.linkSystemLibrary("SDL2"); + }, + .fbev => { + ngui.addCSourceFiles(lvgl_fbev_src, lvgl_flags); + ngui.addCSourceFile("src/ui/c/drv_fbev.c", ngui_cflags); + ngui.defineCMacro("NM_DRV_FBEV", null); + ngui.defineCMacro("USE_FBDEV", null); + ngui.defineCMacro("USE_EVDEV", null); + }, } - const run_step = b.step("run", "Run the app"); - run_step.dependOn(&run_cmd.step); + const ngui_build_step = b.step("ngui", "build ngui (nakamochi gui)"); + ngui_build_step.dependOn(&b.addInstallArtifact(ngui).step); + + // daemon build + const nd = b.addExecutable("nd", "src/nd.zig"); + nd.setTarget(target); + nd.setBuildMode(mode); + nd.pie = true; + nd.strip = strip; + + nifbuild.addPkg(b, nd, "lib/nif"); + const niflib = nifbuild.library(b, "lib/nif"); + niflib.setTarget(target); + niflib.setBuildMode(mode); + nd.linkLibrary(niflib); - const exe_tests = b.addTest("src/main.zig"); - exe_tests.setTarget(target); - exe_tests.setBuildMode(mode); + const nd_build_step = b.step("nd", "build nd (nakamochi daemon)"); + nd_build_step.dependOn(&b.addInstallArtifact(nd).step); - const test_step = b.step("test", "Run unit tests"); - test_step.dependOn(&exe_tests.step); + // default build + const build_all_step = b.step("all", "build everything"); + build_all_step.dependOn(ngui_build_step); + build_all_step.dependOn(nd_build_step); + b.default_step.dependOn(build_all_step); + + { + const tests = b.addTest("src/test.zig"); + tests.setTarget(target); + tests.setBuildMode(mode); + tests.linkLibC(); + if (b.args) |args| { + for (args) |a, i| { + if (std.mem.eql(u8, a, "--test-filter")) { + tests.setFilter(args[i + 1]); // don't care about OOB + break; + } + } + } + + const test_step = b.step("test", "run tests"); + test_step.dependOn(&tests.step); + } } + +const DriverTarget = enum { + sdl2, + fbev, // framebuffer + evdev +}; + +const lvgl_sdl2_src: []const []const u8 = &.{ + "lib/lv_drivers/sdl/sdl.c", + "lib/lv_drivers/sdl/sdl_common.c", +}; + +const lvgl_fbev_src: []const []const u8 = &.{ + "lib/lv_drivers/display/fbdev.c", + "lib/lv_drivers/indev/evdev.c", +}; + +const lvgl_generic_src: []const []const u8 = &.{ + "lib/lvgl/src/core/lv_disp.c", + "lib/lvgl/src/core/lv_event.c", + "lib/lvgl/src/core/lv_group.c", + "lib/lvgl/src/core/lv_indev.c", + "lib/lvgl/src/core/lv_indev_scroll.c", + "lib/lvgl/src/core/lv_obj.c", + "lib/lvgl/src/core/lv_obj_class.c", + "lib/lvgl/src/core/lv_obj_draw.c", + "lib/lvgl/src/core/lv_obj_pos.c", + "lib/lvgl/src/core/lv_obj_scroll.c", + "lib/lvgl/src/core/lv_obj_style.c", + "lib/lvgl/src/core/lv_obj_style_gen.c", + "lib/lvgl/src/core/lv_obj_tree.c", + "lib/lvgl/src/core/lv_refr.c", + "lib/lvgl/src/core/lv_theme.c", + "lib/lvgl/src/draw/arm2d/lv_gpu_arm2d.c", + "lib/lvgl/src/draw/lv_draw.c", + "lib/lvgl/src/draw/lv_draw_arc.c", + "lib/lvgl/src/draw/lv_draw_img.c", + "lib/lvgl/src/draw/lv_draw_label.c", + "lib/lvgl/src/draw/lv_draw_layer.c", + "lib/lvgl/src/draw/lv_draw_line.c", + "lib/lvgl/src/draw/lv_draw_mask.c", + "lib/lvgl/src/draw/lv_draw_rect.c", + "lib/lvgl/src/draw/lv_draw_transform.c", + "lib/lvgl/src/draw/lv_draw_triangle.c", + "lib/lvgl/src/draw/lv_img_buf.c", + "lib/lvgl/src/draw/lv_img_cache.c", + "lib/lvgl/src/draw/lv_img_decoder.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl_arc.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl_bg.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl_composite.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl_img.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl_label.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl_layer.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl_line.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl_mask.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl_polygon.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl_rect.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl_stack_blur.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl_texture_cache.c", + "lib/lvgl/src/draw/sdl/lv_draw_sdl_utils.c", + "lib/lvgl/src/draw/sw/lv_draw_sw.c", + "lib/lvgl/src/draw/sw/lv_draw_sw_arc.c", + "lib/lvgl/src/draw/sw/lv_draw_sw_blend.c", + "lib/lvgl/src/draw/sw/lv_draw_sw_dither.c", + "lib/lvgl/src/draw/sw/lv_draw_sw_gradient.c", + "lib/lvgl/src/draw/sw/lv_draw_sw_img.c", + "lib/lvgl/src/draw/sw/lv_draw_sw_layer.c", + "lib/lvgl/src/draw/sw/lv_draw_sw_letter.c", + "lib/lvgl/src/draw/sw/lv_draw_sw_line.c", + "lib/lvgl/src/draw/sw/lv_draw_sw_polygon.c", + "lib/lvgl/src/draw/sw/lv_draw_sw_rect.c", + "lib/lvgl/src/draw/sw/lv_draw_sw_transform.c", + "lib/lvgl/src/extra/layouts/flex/lv_flex.c", + "lib/lvgl/src/extra/layouts/grid/lv_grid.c", + "lib/lvgl/src/extra/libs/bmp/lv_bmp.c", + "lib/lvgl/src/extra/libs/ffmpeg/lv_ffmpeg.c", + "lib/lvgl/src/extra/libs/freetype/lv_freetype.c", + "lib/lvgl/src/extra/libs/fsdrv/lv_fs_fatfs.c", + "lib/lvgl/src/extra/libs/fsdrv/lv_fs_posix.c", + "lib/lvgl/src/extra/libs/fsdrv/lv_fs_stdio.c", + "lib/lvgl/src/extra/libs/fsdrv/lv_fs_win32.c", + "lib/lvgl/src/extra/libs/gif/gifdec.c", + "lib/lvgl/src/extra/libs/gif/lv_gif.c", + "lib/lvgl/src/extra/libs/png/lodepng.c", + "lib/lvgl/src/extra/libs/png/lv_png.c", + "lib/lvgl/src/extra/libs/qrcode/lv_qrcode.c", + "lib/lvgl/src/extra/libs/qrcode/qrcodegen.c", + "lib/lvgl/src/extra/libs/rlottie/lv_rlottie.c", + "lib/lvgl/src/extra/libs/sjpg/lv_sjpg.c", + "lib/lvgl/src/extra/libs/sjpg/tjpgd.c", + "lib/lvgl/src/extra/lv_extra.c", + "lib/lvgl/src/extra/others/fragment/lv_fragment.c", + "lib/lvgl/src/extra/others/fragment/lv_fragment_manager.c", + "lib/lvgl/src/extra/others/gridnav/lv_gridnav.c", + "lib/lvgl/src/extra/others/ime/lv_ime_pinyin.c", + "lib/lvgl/src/extra/others/imgfont/lv_imgfont.c", + "lib/lvgl/src/extra/others/monkey/lv_monkey.c", + "lib/lvgl/src/extra/others/msg/lv_msg.c", + "lib/lvgl/src/extra/others/snapshot/lv_snapshot.c", + "lib/lvgl/src/extra/themes/basic/lv_theme_basic.c", + "lib/lvgl/src/extra/themes/default/lv_theme_default.c", + "lib/lvgl/src/extra/themes/mono/lv_theme_mono.c", + "lib/lvgl/src/extra/widgets/animimg/lv_animimg.c", + "lib/lvgl/src/extra/widgets/calendar/lv_calendar.c", + "lib/lvgl/src/extra/widgets/calendar/lv_calendar_header_arrow.c", + "lib/lvgl/src/extra/widgets/calendar/lv_calendar_header_dropdown.c", + "lib/lvgl/src/extra/widgets/chart/lv_chart.c", + "lib/lvgl/src/extra/widgets/colorwheel/lv_colorwheel.c", + "lib/lvgl/src/extra/widgets/imgbtn/lv_imgbtn.c", + "lib/lvgl/src/extra/widgets/keyboard/lv_keyboard.c", + "lib/lvgl/src/extra/widgets/led/lv_led.c", + "lib/lvgl/src/extra/widgets/list/lv_list.c", + "lib/lvgl/src/extra/widgets/menu/lv_menu.c", + "lib/lvgl/src/extra/widgets/meter/lv_meter.c", + "lib/lvgl/src/extra/widgets/msgbox/lv_msgbox.c", + "lib/lvgl/src/extra/widgets/span/lv_span.c", + "lib/lvgl/src/extra/widgets/spinbox/lv_spinbox.c", + "lib/lvgl/src/extra/widgets/spinner/lv_spinner.c", + "lib/lvgl/src/extra/widgets/tabview/lv_tabview.c", + "lib/lvgl/src/extra/widgets/tileview/lv_tileview.c", + "lib/lvgl/src/extra/widgets/win/lv_win.c", + "lib/lvgl/src/font/lv_font.c", + "lib/lvgl/src/font/lv_font_fmt_txt.c", + "lib/lvgl/src/font/lv_font_loader.c", + "lib/lvgl/src/hal/lv_hal_disp.c", + "lib/lvgl/src/hal/lv_hal_indev.c", + "lib/lvgl/src/hal/lv_hal_tick.c", + "lib/lvgl/src/misc/lv_anim.c", + "lib/lvgl/src/misc/lv_anim_timeline.c", + "lib/lvgl/src/misc/lv_area.c", + "lib/lvgl/src/misc/lv_async.c", + "lib/lvgl/src/misc/lv_bidi.c", + "lib/lvgl/src/misc/lv_color.c", + "lib/lvgl/src/misc/lv_fs.c", + "lib/lvgl/src/misc/lv_gc.c", + "lib/lvgl/src/misc/lv_ll.c", + "lib/lvgl/src/misc/lv_log.c", + "lib/lvgl/src/misc/lv_lru.c", + "lib/lvgl/src/misc/lv_math.c", + "lib/lvgl/src/misc/lv_mem.c", + "lib/lvgl/src/misc/lv_printf.c", + "lib/lvgl/src/misc/lv_style.c", + "lib/lvgl/src/misc/lv_style_gen.c", + "lib/lvgl/src/misc/lv_templ.c", + "lib/lvgl/src/misc/lv_timer.c", + "lib/lvgl/src/misc/lv_tlsf.c", + "lib/lvgl/src/misc/lv_txt.c", + "lib/lvgl/src/misc/lv_txt_ap.c", + "lib/lvgl/src/misc/lv_utils.c", + "lib/lvgl/src/widgets/lv_arc.c", + "lib/lvgl/src/widgets/lv_bar.c", + "lib/lvgl/src/widgets/lv_btn.c", + "lib/lvgl/src/widgets/lv_btnmatrix.c", + "lib/lvgl/src/widgets/lv_canvas.c", + "lib/lvgl/src/widgets/lv_checkbox.c", + "lib/lvgl/src/widgets/lv_dropdown.c", + "lib/lvgl/src/widgets/lv_img.c", + "lib/lvgl/src/widgets/lv_label.c", + "lib/lvgl/src/widgets/lv_line.c", + "lib/lvgl/src/widgets/lv_objx_templ.c", + "lib/lvgl/src/widgets/lv_roller.c", + "lib/lvgl/src/widgets/lv_slider.c", + "lib/lvgl/src/widgets/lv_switch.c", + "lib/lvgl/src/widgets/lv_table.c", + "lib/lvgl/src/widgets/lv_textarea.c", +}; diff --git a/doc/fonts.md b/doc/fonts.md new file mode 100644 index 0000000..bddc31d --- /dev/null +++ b/doc/fonts.md @@ -0,0 +1,73 @@ +the trouble is fontawesome now supplies multiple files, +fa-brands-400.woff2, fa-regular-400.woff2 and fa-solid-900.woff2. +don't know which symbol is in which file. + +list all defined symbols into a file: + + grep 0x ../ngui/lib/lvgl/src/font/lv_symbol_def.h | grep -v 0x2022 | \ + cut -d, -f2 | cut -c4-7 | tr 'A-F' 'a-f' \ + > /tmp/sym.txt + +download and unzip fontawesome. expect to find metadata/icons.yml file. +grep metadata to find out which set each icon is in: + + for c in $(cat /tmp/sym.txt); do + t=$(grep -B3 "unicode: $c" metadata/icons.yml | grep -- '- ' | head -n1 | tr -d ' -') + echo "$c\t$t" + done + +some icons are in multiple styles. search for the code on https://fontawesome.com/icons/ +and compare to the image on https://docs.lvgl.io/8.3/overview/font.html. +the command above takes the first one listed in icons.yml, which is usually "solid". +when searching on fontawesome, make sure it's a free icon, as opposed to their pro version. + +not all icons might be present. at the time of writing, the following codes are amiss: + +- 0xf067 `LV_SYMBOL_PLUS`; actually exists but listed as unicode:2b in icons.yml +- 0xf8a2 `LV_SYMBOL_NEW_LINE`; looks like fontawesome removed `level-down-alt` from v6 +so i picked an alternative 0xf177 `arrow-left-long` + +dump previous command output into an fa-icon-style.txt file. add missing "solid" style +in the second column and replace f8a2 with `f177=>0xf8a2` mapping. the latter is +the syntax for when running [lvgl font convertion tool](https://github.com/lvgl/lv_font_conv). + +while there, add more codes to the file, separating columns with a single tab: + +- 0xf379 brands (bitcoin) +- 0xe0b4 solid (bitcoin-sign) +- 0xf0e7 solid (lightning bolt) + +split the previously generated fa-icon-style.txt file into chunks suitable for +constructing lvgl's font converter arguments. + +first, check which styles are present. at the moment, only "brands" and "solid" +are used: + + $ cut -f2 fa-icon-style.txt | sort | uniq -c + 3 brands + 61 solid + +then split the file, for each style from the previous command. example for "solid": + + grep solid fa-icon-style.txt | cut -f1 | tr 'a-f' 'A-F' | \ + while IFS= read -r line; do printf "0x$line\n"; done | \ + paste -s -d, | tr -d '\n' > fa-solid.txt + +typically, you'll want to bundle the symbols from fontawesome with a regular font. +i'll use [courier prime code](https://github.com/quoteunquoteapps/courierprimecode) +as an example. + +install the font converter tool; requires nodejs: + + npm i lvgl/lv_font_conv + +finally, convert and bundle all fonts, for 14px size as an example: + + ./node_modules/.bin/lv_font_conv --no-compress --no-prefilter --bpp 4 --size 14 \ + --font courier-prime-code.ttf -r 0x20-0x7F,0xB0,0x2022 \ + --font fa-brands-400.ttf -r $(cat fa-brands.txt) \ + --font fa-solid-900.ttf -r $(cat fa-solid.txt) \ + --format lvgl --force-fast-kern-format \ + -o lv_font_courierprimecode_14.c + +the arguments are similar to those in the header of any LVGL font in `lib/lvgl/src/font/lv_font/xxx.c`. diff --git a/lib/nif/build.zig b/lib/nif/build.zig new file mode 100644 index 0000000..41a7c06 --- /dev/null +++ b/lib/nif/build.zig @@ -0,0 +1,29 @@ +const build = @import("std").build; + +pub fn addPkg(b: *build.Builder, obj: *build.LibExeObjStep, prefix: []const u8) void { + obj.addPackagePath("nif", pkgPath(b, prefix)); +} + +pub fn pkgPath(b: *build.Builder, prefix: []const u8) []const u8 { + return b.pathJoin(&.{prefix, "nif.zig"}); +} + +pub fn library(b: *build.Builder, prefix: []const u8) *build.LibExeObjStep { + const lib = b.addStaticLibrary("nif", b.pathJoin(&.{prefix, "nif.zig"})); + lib.addIncludePath(b.pathJoin(&.{prefix, "wpa_supplicant"})); + lib.defineCMacro("CONFIG_CTRL_IFACE", null); + lib.defineCMacro("CONFIG_CTRL_IFACE_UNIX", null); + lib.addCSourceFiles(&.{ + b.pathJoin(&.{prefix, "wpa_supplicant/wpa_ctrl.c"}), + b.pathJoin(&.{prefix, "wpa_supplicant/os_unix.c"}), + }, &.{ + "-Wall", + "-Wextra", + "-Wshadow", + "-Wundef", + "-Wunused-parameter", + "-Werror", + }); + lib.linkLibC(); + return lib; +} diff --git a/lib/nif/nif.zig b/lib/nif/nif.zig new file mode 100644 index 0000000..40897ad --- /dev/null +++ b/lib/nif/nif.zig @@ -0,0 +1,63 @@ +const std = @import("std"); +const mem = std.mem; +const net = std.net; +const os = std.os; + +pub const wpa = @import("wpa.zig"); + +const IFF_UP = 1 << 0; //0b1; +const IFF_LOOPBACK = 1 << 3; //0b1000; + +const ifaddrs = extern struct { + next: ?*ifaddrs, + name: [*:0]const u8, + flags: c_uint, // see IFF_xxx SIOCGIFFLAGS in netdevice(7) + addr: ?*std.os.sockaddr, + netmask: ?*std.os.sockaddr, + ifu: extern union { + broad: *os.sockaddr, // flags & IFF_BROADCAST + dst: *os.sockaddr, // flags & IFF_POINTOPOINT + }, + data: ?*anyopaque, +}; + +extern "c" fn getifaddrs(ptrp: **ifaddrs) c_int; +extern "c" fn freeifaddrs(ptr: *ifaddrs) void; + +/// retrieves a list of all public IP addresses assigned to the network interfaces, +/// optionally filtering by the interface name. +/// caller owns the returned value. +pub fn pubAddresses(allocator: mem.Allocator, ifname: ?[]const u8) ![]net.Address { + var res: *ifaddrs = undefined; + if (getifaddrs(&res) != 0) { + return error.Getifaddrs; + } + defer freeifaddrs(res); + + var list = std.ArrayList(net.Address).init(allocator); + var it: ?*ifaddrs = res; + while (it) |ifa| : (it = ifa.next) { + const sa: *os.sockaddr = ifa.addr orelse continue; + if (sa.family != os.AF.INET and sa.family != os.AF.INET6) { + // not an IP address + continue; + } + if (ifa.flags & IFF_UP == 0 or ifa.flags & IFF_LOOPBACK != 0) { + // skip loopbacks and those which are not "up" + continue; + } + const ipaddr = net.Address.initPosix(@alignCast(4, sa)); // initPosix makes a copy + if (ipaddr.any.family == os.AF.INET6 and ipaddr.in6.sa.scope_id > 0) { + // want only global, with 0 scope + // non-zero scopes make sense for link-local addr only. + continue; + } + if (ifname) |name| { + if (!mem.eql(u8, name, mem.sliceTo(ifa.name, 0))) { + continue; + } + } + try list.append(ipaddr); + } + return list.toOwnedSlice(); +} diff --git a/lib/nif/wpa.zig b/lib/nif/wpa.zig new file mode 100644 index 0000000..c403fdd --- /dev/null +++ b/lib/nif/wpa.zig @@ -0,0 +1,384 @@ +const std = @import("std"); +const mem = std.mem; +const Thread = std.Thread; + +const WPACtrl = opaque {}; +const WPAReqCallback = *const fn ([*:0]const u8, usize) callconv(.C) void; + +extern fn wpa_ctrl_open(ctrl_path: [*:0]const u8) ?*WPACtrl; +extern fn wpa_ctrl_close(ctrl: *WPACtrl) void; +extern fn wpa_ctrl_request(ctrl: *WPACtrl, cmd: [*:0]const u8, clen: usize, reply: [*:0]u8, rlen: *usize, cb: ?WPAReqCallback) c_int; +extern fn wpa_ctrl_pending(ctrl: *WPACtrl) c_int; +extern fn wpa_ctrl_recv(ctrl: *WPACtrl, reply: [*:0]u8, reply_len: *usize) c_int; + +pub const Control = struct { + //mu: Thread.Mutext = .{}, + wpa_ctrl: *WPACtrl, + attached: bool = false, + + const Self = @This(); + pub const Error = error{ + NameTooLong, + WpaCtrlFailure, + WpaCtrlTimeout, + WpaCtrlAttach, + WpaCtrlDetach, + WpaCtrlScanStart, + WpaCtrlSaveConfig, + WpaCtrlAddNetwork, + WpaCtrlRemoveNetwork, + WpaCtrlSelectNetwork, + WpaCtrlEnableNetwork, + WpaCtrlSetNetworkParam, + } || std.fmt.BufPrintError; + + // TODO: using this in Self.request + pub const RequestCallback = *const fn (msg: [:0]const u8) void; + + fn wpaErr(i: c_int) Error { + return switch (i) { + -2 => error.WpaCtrlTimeout, + else => error.WpaCtrlFailure, + }; + } + + /// open a WPA control interface identified by the path. + /// the returned instance must be close'd when done to free resources. + /// TODO: describe @android: and @abstract: prefixes + /// TODO: what about UDP, on windows? + pub fn open(path: [:0]const u8) Error!Self { + const ctrl = wpa_ctrl_open(path); + if (ctrl == null) { + return error.WpaCtrlFailure; + } + return Self{ .wpa_ctrl = ctrl.? }; + } + + /// release all associated resources, including detach'ing a monitor. + pub fn close(self: *Self) Error!void { + //self.mu.lock(); + //defer self.mu.unlock(); + if (self.attached) { + try self.detach(); + } + wpa_ctrl_close(self.wpa_ctrl); + } + + /// start control interface events monitoring. + /// presence of events is reported by self.pending; then can be read using self.receive. + pub fn attach(self: *Self) Error!void { + self.reqOK("ATTACH") catch return error.WpaCtrlAttach; + self.attached = true; + } + + /// stop control interface events monitoring. + pub fn detach(self: *Self) Error!void { + self.reqOK("DETACH") catch return error.WpaCtrlDetach; + self.attached = false; + } + + /// request wifi scan + pub fn scan(self: *Self) Error!void { + self.reqOK("SCAN") catch return error.WpaCtrlScanStart; + } + + /// dump in-memory config to a file, typically /etc/wpa_supplicant/wpa_supplicant.conf. + /// fails if update_config set to 0. + pub fn saveConfig(self: *Self) Error!void { + self.reqOK("SAVE_CONFIG") catch return error.WpaCtrlSaveConfig; + } + + /// add a new blank network, returning its ID. + /// the newly added network can be configured with self.setNetworkParam. + pub fn addNetwork(self: *Self) (Error||std.fmt.ParseIntError)!u32 { + var buf: [10:0]u8 = undefined; + const resp = self.request("ADD_NETWORK", &buf, null) catch return error.WpaCtrlAddNetwork; + return std.fmt.parseUnsigned(u32, mem.trim(u8, resp, "\n "), 10); + } + + pub fn removeNetwork(self: *Self, id: u32) Error!void { + var buf: [48:0]u8 = undefined; + const cmd = try std.fmt.bufPrintZ(&buf, "REMOVE_NETWORK {d}", .{id}); + return self.reqOK(cmd) catch return error.WpaCtrlRemoveNetwork; + } + + pub fn selectNetwork(self: *Self, id: u32) Error!void { + var buf: [48:0]u8 = undefined; + const cmd = try std.fmt.bufPrintZ(&buf, "SELECT_NETWORK {d}", .{id}); + return self.reqOK(cmd) catch return error.WpaCtrlSelectNetwork; + } + + pub fn enableNetwork(self: *Self, id: u32) Error!void { + var buf: [48:0]u8 = undefined; + const cmd = try std.fmt.bufPrintZ(&buf, "ENABLE_NETWORK {d}", .{id}); + return self.reqOK(cmd) catch return error.WpaCtrlEnableNetwork; + } + + pub fn setNetworkParam(self: *Self, id: u32, name: []const u8, value: []const u8) Error!void { + var buf: [512:0]u8 = undefined; + const cmd = try std.fmt.bufPrintZ(&buf, "SET_NETWORK {d} {s} {s}", .{id, name, value}); + return self.reqOK(cmd) catch return error.WpaCtrlSetNetworkParam; + } + + fn reqOK(self: *Self, cmd: [:0]const u8) Error!void { + var buf: [10:0]u8 = undefined; + const resp = try self.request(cmd, &buf, null); + if (!mem.startsWith(u8, resp, "OK\n")) { + return error.WpaCtrlFailure; + } + } + + /// send a command to the control interface, returning a response owned by buf. + /// callback receives a message from the same buf. + pub fn request(self: Self, cmd: [:0]const u8, buf: [:0]u8, callback: ?WPAReqCallback) Error![]const u8 { + //self.mu.lock(); + //defer self.mu.unlock(); + var n: usize = buf.len; + const e = wpa_ctrl_request(self.wpa_ctrl, cmd, cmd.len, buf, &n, callback); + if (e != 0) { + return wpaErr(e); + } + return buf[0..n]; + } + + /// reports whether pending messages are waiting to be read using self.receive. + /// requires self to be attach'ed. + pub fn pending(self: Self) Error!bool { + //self.mu.lock(); + //defer self.mu.unlock(); + const n = wpa_ctrl_pending(self.wpa_ctrl); + if (n < 0) { + return wpaErr(n); + } + return n > 0; + } + + /// retrieve a pending message using the provided buf. + /// returned slice is owned by the buf. + /// requires self to be attach'ed. + pub fn receive(self: Self, buf: [:0]u8) Error![]const u8 { + //self.mu.lock(); + //defer self.mu.unlock(); + var n: usize = buf.len; + const e = wpa_ctrl_recv(self.wpa_ctrl, buf, &n); + if (e != 0) { + return wpaErr(e); + } + return buf[0..n]; + } +}; + +//pub const WPA_CTRL_REQ = "CTRL-REQ-"; +//pub const WPA_CTRL_RSP = "CTRL-RSP-"; +//pub const WPA_EVENT_CONNECTED = "CTRL-EVENT-CONNECTED "; +//pub const WPA_EVENT_DISCONNECTED = "CTRL-EVENT-DISCONNECTED "; +//pub const WPA_EVENT_ASSOC_REJECT = "CTRL-EVENT-ASSOC-REJECT "; +//pub const WPA_EVENT_AUTH_REJECT = "CTRL-EVENT-AUTH-REJECT "; +//pub const WPA_EVENT_TERMINATING = "CTRL-EVENT-TERMINATING "; +//pub const WPA_EVENT_PASSWORD_CHANGED = "CTRL-EVENT-PASSWORD-CHANGED "; +//pub const WPA_EVENT_EAP_NOTIFICATION = "CTRL-EVENT-EAP-NOTIFICATION "; +//pub const WPA_EVENT_EAP_STARTED = "CTRL-EVENT-EAP-STARTED "; +//pub const WPA_EVENT_EAP_PROPOSED_METHOD = "CTRL-EVENT-EAP-PROPOSED-METHOD "; +//pub const WPA_EVENT_EAP_METHOD = "CTRL-EVENT-EAP-METHOD "; +//pub const WPA_EVENT_EAP_PEER_CERT = "CTRL-EVENT-EAP-PEER-CERT "; +//pub const WPA_EVENT_EAP_PEER_ALT = "CTRL-EVENT-EAP-PEER-ALT "; +//pub const WPA_EVENT_EAP_TLS_CERT_ERROR = "CTRL-EVENT-EAP-TLS-CERT-ERROR "; +//pub const WPA_EVENT_EAP_STATUS = "CTRL-EVENT-EAP-STATUS "; +//pub const WPA_EVENT_EAP_RETRANSMIT = "CTRL-EVENT-EAP-RETRANSMIT "; +//pub const WPA_EVENT_EAP_RETRANSMIT2 = "CTRL-EVENT-EAP-RETRANSMIT2 "; +//pub const WPA_EVENT_EAP_SUCCESS = "CTRL-EVENT-EAP-SUCCESS "; +//pub const WPA_EVENT_EAP_SUCCESS2 = "CTRL-EVENT-EAP-SUCCESS2 "; +//pub const WPA_EVENT_EAP_FAILURE = "CTRL-EVENT-EAP-FAILURE "; +//pub const WPA_EVENT_EAP_FAILURE2 = "CTRL-EVENT-EAP-FAILURE2 "; +//pub const WPA_EVENT_EAP_TIMEOUT_FAILURE = "CTRL-EVENT-EAP-TIMEOUT-FAILURE "; +//pub const WPA_EVENT_EAP_TIMEOUT_FAILURE2 = "CTRL-EVENT-EAP-TIMEOUT-FAILURE2 "; +//pub const WPA_EVENT_EAP_ERROR_CODE = "EAP-ERROR-CODE "; +//pub const WPA_EVENT_TEMP_DISABLED = "CTRL-EVENT-SSID-TEMP-DISABLED "; +//pub const WPA_EVENT_REENABLED = "CTRL-EVENT-SSID-REENABLED "; +//pub const WPA_EVENT_SCAN_STARTED = "CTRL-EVENT-SCAN-STARTED "; +//pub const WPA_EVENT_SCAN_RESULTS = "CTRL-EVENT-SCAN-RESULTS "; +//pub const WPA_EVENT_SCAN_FAILED = "CTRL-EVENT-SCAN-FAILED "; +//pub const WPA_EVENT_STATE_CHANGE = "CTRL-EVENT-STATE-CHANGE "; +//pub const WPA_EVENT_BSS_ADDED = "CTRL-EVENT-BSS-ADDED "; +//pub const WPA_EVENT_BSS_REMOVED = "CTRL-EVENT-BSS-REMOVED "; +//pub const WPA_EVENT_NETWORK_NOT_FOUND = "CTRL-EVENT-NETWORK-NOT-FOUND "; +//pub const WPA_EVENT_SIGNAL_CHANGE = "CTRL-EVENT-SIGNAL-CHANGE "; +//pub const WPA_EVENT_BEACON_LOSS = "CTRL-EVENT-BEACON-LOSS "; +//pub const WPA_EVENT_REGDOM_CHANGE = "CTRL-EVENT-REGDOM-CHANGE "; +//pub const WPA_EVENT_CHANNEL_SWITCH_STARTED = "CTRL-EVENT-STARTED-CHANNEL-SWITCH "; +//pub const WPA_EVENT_CHANNEL_SWITCH = "CTRL-EVENT-CHANNEL-SWITCH "; +//pub const WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER = "CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER "; +//pub const WPA_EVENT_UNPROT_BEACON = "CTRL-EVENT-UNPROT-BEACON "; +//pub const WPA_EVENT_DO_ROAM = "CTRL-EVENT-DO-ROAM "; +//pub const WPA_EVENT_SKIP_ROAM = "CTRL-EVENT-SKIP-ROAM "; +//pub const WPA_EVENT_SUBNET_STATUS_UPDATE = "CTRL-EVENT-SUBNET-STATUS-UPDATE "; +//pub const IBSS_RSN_COMPLETED = "IBSS-RSN-COMPLETED "; +//pub const WPA_EVENT_FREQ_CONFLICT = "CTRL-EVENT-FREQ-CONFLICT "; +//pub const WPA_EVENT_AVOID_FREQ = "CTRL-EVENT-AVOID-FREQ "; +//pub const WPA_EVENT_NETWORK_ADDED = "CTRL-EVENT-NETWORK-ADDED "; +//pub const WPA_EVENT_NETWORK_REMOVED = "CTRL-EVENT-NETWORK-REMOVED "; +//pub const WPA_EVENT_MSCS_RESULT = "CTRL-EVENT-MSCS-RESULT "; +//pub const WPS_EVENT_OVERLAP = "WPS-OVERLAP-DETECTED "; +//pub const WPS_EVENT_AP_AVAILABLE_PBC = "WPS-AP-AVAILABLE-PBC "; +//pub const WPS_EVENT_AP_AVAILABLE_AUTH = "WPS-AP-AVAILABLE-AUTH "; +//pub const WPS_EVENT_AP_AVAILABLE_PIN = "WPS-AP-AVAILABLE-PIN "; +//pub const WPS_EVENT_AP_AVAILABLE = "WPS-AP-AVAILABLE "; +//pub const WPS_EVENT_CRED_RECEIVED = "WPS-CRED-RECEIVED "; +//pub const WPS_EVENT_M2D = "WPS-M2D "; +//pub const WPS_EVENT_FAIL = "WPS-FAIL "; +//pub const WPS_EVENT_SUCCESS = "WPS-SUCCESS "; +//pub const WPS_EVENT_TIMEOUT = "WPS-TIMEOUT "; +//pub const WPS_EVENT_ACTIVE = "WPS-PBC-ACTIVE "; +//pub const WPS_EVENT_DISABLE = "WPS-PBC-DISABLE "; +//pub const WPS_EVENT_ENROLLEE_SEEN = "WPS-ENROLLEE-SEEN "; +//pub const WPS_EVENT_OPEN_NETWORK = "WPS-OPEN-NETWORK "; +//pub const WPA_EVENT_SCS_RESULT = "CTRL-EVENT-SCS-RESULT "; +//pub const WPA_EVENT_DSCP_POLICY = "CTRL-EVENT-DSCP-POLICY "; +//pub const WPS_EVENT_ER_AP_ADD = "WPS-ER-AP-ADD "; +//pub const WPS_EVENT_ER_AP_REMOVE = "WPS-ER-AP-REMOVE "; +//pub const WPS_EVENT_ER_ENROLLEE_ADD = "WPS-ER-ENROLLEE-ADD "; +//pub const WPS_EVENT_ER_ENROLLEE_REMOVE = "WPS-ER-ENROLLEE-REMOVE "; +//pub const WPS_EVENT_ER_AP_SETTINGS = "WPS-ER-AP-SETTINGS "; +//pub const WPS_EVENT_ER_SET_SEL_REG = "WPS-ER-AP-SET-SEL-REG "; +//pub const DPP_EVENT_AUTH_SUCCESS = "DPP-AUTH-SUCCESS "; +//pub const DPP_EVENT_AUTH_INIT_FAILED = "DPP-AUTH-INIT-FAILED "; +//pub const DPP_EVENT_NOT_COMPATIBLE = "DPP-NOT-COMPATIBLE "; +//pub const DPP_EVENT_RESPONSE_PENDING = "DPP-RESPONSE-PENDING "; +//pub const DPP_EVENT_SCAN_PEER_QR_CODE = "DPP-SCAN-PEER-QR-CODE "; +//pub const DPP_EVENT_AUTH_DIRECTION = "DPP-AUTH-DIRECTION "; +//pub const DPP_EVENT_CONF_RECEIVED = "DPP-CONF-RECEIVED "; +//pub const DPP_EVENT_CONF_SENT = "DPP-CONF-SENT "; +//pub const DPP_EVENT_CONF_FAILED = "DPP-CONF-FAILED "; +//pub const DPP_EVENT_CONN_STATUS_RESULT = "DPP-CONN-STATUS-RESULT "; +//pub const DPP_EVENT_CONFOBJ_AKM = "DPP-CONFOBJ-AKM "; +//pub const DPP_EVENT_CONFOBJ_SSID = "DPP-CONFOBJ-SSID "; +//pub const DPP_EVENT_CONFOBJ_SSID_CHARSET = "DPP-CONFOBJ-SSID-CHARSET "; +//pub const DPP_EVENT_CONFOBJ_PASS = "DPP-CONFOBJ-PASS "; +//pub const DPP_EVENT_CONFOBJ_PSK = "DPP-CONFOBJ-PSK "; +//pub const DPP_EVENT_CONNECTOR = "DPP-CONNECTOR "; +//pub const DPP_EVENT_C_SIGN_KEY = "DPP-C-SIGN-KEY "; +//pub const DPP_EVENT_PP_KEY = "DPP-PP-KEY "; +//pub const DPP_EVENT_NET_ACCESS_KEY = "DPP-NET-ACCESS-KEY "; +//pub const DPP_EVENT_SERVER_NAME = "DPP-SERVER-NAME "; +//pub const DPP_EVENT_CERTBAG = "DPP-CERTBAG "; +//pub const DPP_EVENT_CACERT = "DPP-CACERT "; +//pub const DPP_EVENT_MISSING_CONNECTOR = "DPP-MISSING-CONNECTOR "; +//pub const DPP_EVENT_NETWORK_ID = "DPP-NETWORK-ID "; +//pub const DPP_EVENT_CONFIGURATOR_ID = "DPP-CONFIGURATOR-ID "; +//pub const DPP_EVENT_RX = "DPP-RX "; +//pub const DPP_EVENT_TX = "DPP-TX "; +//pub const DPP_EVENT_TX_STATUS = "DPP-TX-STATUS "; +//pub const DPP_EVENT_FAIL = "DPP-FAIL "; +//pub const DPP_EVENT_PKEX_T_LIMIT = "DPP-PKEX-T-LIMIT "; +//pub const DPP_EVENT_INTRO = "DPP-INTRO "; +//pub const DPP_EVENT_CONF_REQ_RX = "DPP-CONF-REQ-RX "; +//pub const DPP_EVENT_CHIRP_STOPPED = "DPP-CHIRP-STOPPED "; +//pub const DPP_EVENT_MUD_URL = "DPP-MUD-URL "; +//pub const DPP_EVENT_BAND_SUPPORT = "DPP-BAND-SUPPORT "; +//pub const DPP_EVENT_CSR = "DPP-CSR "; +//pub const DPP_EVENT_CHIRP_RX = "DPP-CHIRP-RX "; +//pub const MESH_GROUP_STARTED = "MESH-GROUP-STARTED "; +//pub const MESH_GROUP_REMOVED = "MESH-GROUP-REMOVED "; +//pub const MESH_PEER_CONNECTED = "MESH-PEER-CONNECTED "; +//pub const MESH_PEER_DISCONNECTED = "MESH-PEER-DISCONNECTED "; +//pub const MESH_SAE_AUTH_FAILURE = "MESH-SAE-AUTH-FAILURE "; +//pub const MESH_SAE_AUTH_BLOCKED = "MESH-SAE-AUTH-BLOCKED "; +//pub const WMM_AC_EVENT_TSPEC_ADDED = "TSPEC-ADDED "; +//pub const WMM_AC_EVENT_TSPEC_REMOVED = "TSPEC-REMOVED "; +//pub const WMM_AC_EVENT_TSPEC_REQ_FAILED = "TSPEC-REQ-FAILED "; +//pub const P2P_EVENT_DEVICE_FOUND = "P2P-DEVICE-FOUND "; +//pub const P2P_EVENT_DEVICE_LOST = "P2P-DEVICE-LOST "; +//pub const P2P_EVENT_GO_NEG_REQUEST = "P2P-GO-NEG-REQUEST "; +//pub const P2P_EVENT_GO_NEG_SUCCESS = "P2P-GO-NEG-SUCCESS "; +//pub const P2P_EVENT_GO_NEG_FAILURE = "P2P-GO-NEG-FAILURE "; +//pub const P2P_EVENT_GROUP_FORMATION_SUCCESS = "P2P-GROUP-FORMATION-SUCCESS "; +//pub const P2P_EVENT_GROUP_FORMATION_FAILURE = "P2P-GROUP-FORMATION-FAILURE "; +//pub const P2P_EVENT_GROUP_STARTED = "P2P-GROUP-STARTED "; +//pub const P2P_EVENT_GROUP_REMOVED = "P2P-GROUP-REMOVED "; +//pub const P2P_EVENT_CROSS_CONNECT_ENABLE = "P2P-CROSS-CONNECT-ENABLE "; +//pub const P2P_EVENT_CROSS_CONNECT_DISABLE = "P2P-CROSS-CONNECT-DISABLE "; +//pub const P2P_EVENT_PROV_DISC_SHOW_PIN = "P2P-PROV-DISC-SHOW-PIN "; +//pub const P2P_EVENT_PROV_DISC_ENTER_PIN = "P2P-PROV-DISC-ENTER-PIN "; +//pub const P2P_EVENT_PROV_DISC_PBC_REQ = "P2P-PROV-DISC-PBC-REQ "; +//pub const P2P_EVENT_PROV_DISC_PBC_RESP = "P2P-PROV-DISC-PBC-RESP "; +//pub const P2P_EVENT_PROV_DISC_FAILURE = "P2P-PROV-DISC-FAILURE"; +//pub const P2P_EVENT_SERV_DISC_REQ = "P2P-SERV-DISC-REQ "; +//pub const P2P_EVENT_SERV_DISC_RESP = "P2P-SERV-DISC-RESP "; +//pub const P2P_EVENT_SERV_ASP_RESP = "P2P-SERV-ASP-RESP "; +//pub const P2P_EVENT_INVITATION_RECEIVED = "P2P-INVITATION-RECEIVED "; +//pub const P2P_EVENT_INVITATION_RESULT = "P2P-INVITATION-RESULT "; +//pub const P2P_EVENT_INVITATION_ACCEPTED = "P2P-INVITATION-ACCEPTED "; +//pub const P2P_EVENT_FIND_STOPPED = "P2P-FIND-STOPPED "; +//pub const P2P_EVENT_PERSISTENT_PSK_FAIL = "P2P-PERSISTENT-PSK-FAIL id="; +//pub const P2P_EVENT_PRESENCE_RESPONSE = "P2P-PRESENCE-RESPONSE "; +//pub const P2P_EVENT_NFC_BOTH_GO = "P2P-NFC-BOTH-GO "; +//pub const P2P_EVENT_NFC_PEER_CLIENT = "P2P-NFC-PEER-CLIENT "; +//pub const P2P_EVENT_NFC_WHILE_CLIENT = "P2P-NFC-WHILE-CLIENT "; +//pub const P2P_EVENT_FALLBACK_TO_GO_NEG = "P2P-FALLBACK-TO-GO-NEG "; +//pub const P2P_EVENT_FALLBACK_TO_GO_NEG_ENABLED = "P2P-FALLBACK-TO-GO-NEG-ENABLED "; +//pub const ESS_DISASSOC_IMMINENT = "ESS-DISASSOC-IMMINENT "; +//pub const P2P_EVENT_REMOVE_AND_REFORM_GROUP = "P2P-REMOVE-AND-REFORM-GROUP "; +//pub const P2P_EVENT_P2PS_PROVISION_START = "P2PS-PROV-START "; +//pub const P2P_EVENT_P2PS_PROVISION_DONE = "P2PS-PROV-DONE "; +//pub const INTERWORKING_AP = "INTERWORKING-AP "; +//pub const INTERWORKING_EXCLUDED = "INTERWORKING-BLACKLISTED "; +//pub const INTERWORKING_NO_MATCH = "INTERWORKING-NO-MATCH "; +//pub const INTERWORKING_ALREADY_CONNECTED = "INTERWORKING-ALREADY-CONNECTED "; +//pub const INTERWORKING_SELECTED = "INTERWORKING-SELECTED "; +//pub const CRED_ADDED = "CRED-ADDED "; +//pub const CRED_MODIFIED = "CRED-MODIFIED "; +//pub const CRED_REMOVED = "CRED-REMOVED "; +//pub const GAS_RESPONSE_INFO = "GAS-RESPONSE-INFO "; +//pub const GAS_QUERY_START = "GAS-QUERY-START "; +//pub const GAS_QUERY_DONE = "GAS-QUERY-DONE "; +//pub const ANQP_QUERY_DONE = "ANQP-QUERY-DONE "; +//pub const RX_ANQP = "RX-ANQP "; +//pub const RX_HS20_ANQP = "RX-HS20-ANQP "; +//pub const RX_HS20_ANQP_ICON = "RX-HS20-ANQP-ICON "; +//pub const RX_HS20_ICON = "RX-HS20-ICON "; +//pub const RX_MBO_ANQP = "RX-MBO-ANQP "; +//pub const RX_VENUE_URL = "RX-VENUE-URL "; +//pub const HS20_SUBSCRIPTION_REMEDIATION = "HS20-SUBSCRIPTION-REMEDIATION "; +//pub const HS20_DEAUTH_IMMINENT_NOTICE = "HS20-DEAUTH-IMMINENT-NOTICE "; +//pub const HS20_T_C_ACCEPTANCE = "HS20-T-C-ACCEPTANCE "; +//pub const EXT_RADIO_WORK_START = "EXT-RADIO-WORK-START "; +//pub const EXT_RADIO_WORK_TIMEOUT = "EXT-RADIO-WORK-TIMEOUT "; +//pub const RRM_EVENT_NEIGHBOR_REP_RXED = "RRM-NEIGHBOR-REP-RECEIVED "; +//pub const RRM_EVENT_NEIGHBOR_REP_FAILED = "RRM-NEIGHBOR-REP-REQUEST-FAILED "; +//pub const WPS_EVENT_PIN_NEEDED = "WPS-PIN-NEEDED "; +//pub const WPS_EVENT_NEW_AP_SETTINGS = "WPS-NEW-AP-SETTINGS "; +//pub const WPS_EVENT_REG_SUCCESS = "WPS-REG-SUCCESS "; +//pub const WPS_EVENT_AP_SETUP_LOCKED = "WPS-AP-SETUP-LOCKED "; +//pub const WPS_EVENT_AP_SETUP_UNLOCKED = "WPS-AP-SETUP-UNLOCKED "; +//pub const WPS_EVENT_AP_PIN_ENABLED = "WPS-AP-PIN-ENABLED "; +//pub const WPS_EVENT_AP_PIN_DISABLED = "WPS-AP-PIN-DISABLED "; +//pub const WPS_EVENT_PIN_ACTIVE = "WPS-PIN-ACTIVE "; +//pub const WPS_EVENT_CANCEL = "WPS-CANCEL "; +//pub const AP_STA_CONNECTED = "AP-STA-CONNECTED "; +//pub const AP_STA_DISCONNECTED = "AP-STA-DISCONNECTED "; +//pub const AP_STA_POSSIBLE_PSK_MISMATCH = "AP-STA-POSSIBLE-PSK-MISMATCH "; +//pub const AP_STA_POLL_OK = "AP-STA-POLL-OK "; +//pub const AP_REJECTED_MAX_STA = "AP-REJECTED-MAX-STA "; +//pub const AP_REJECTED_BLOCKED_STA = "AP-REJECTED-BLOCKED-STA "; +//pub const HS20_T_C_FILTERING_ADD = "HS20-T-C-FILTERING-ADD "; +//pub const HS20_T_C_FILTERING_REMOVE = "HS20-T-C-FILTERING-REMOVE "; +//pub const AP_EVENT_ENABLED = "AP-ENABLED "; +//pub const AP_EVENT_DISABLED = "AP-DISABLED "; +//pub const INTERFACE_ENABLED = "INTERFACE-ENABLED "; +//pub const INTERFACE_DISABLED = "INTERFACE-DISABLED "; +//pub const ACS_EVENT_STARTED = "ACS-STARTED "; +//pub const ACS_EVENT_COMPLETED = "ACS-COMPLETED "; +//pub const ACS_EVENT_FAILED = "ACS-FAILED "; +//pub const DFS_EVENT_RADAR_DETECTED = "DFS-RADAR-DETECTED "; +//pub const DFS_EVENT_NEW_CHANNEL = "DFS-NEW-CHANNEL "; +//pub const DFS_EVENT_CAC_START = "DFS-CAC-START "; +//pub const DFS_EVENT_CAC_COMPLETED = "DFS-CAC-COMPLETED "; +//pub const DFS_EVENT_NOP_FINISHED = "DFS-NOP-FINISHED "; +//pub const DFS_EVENT_PRE_CAC_EXPIRED = "DFS-PRE-CAC-EXPIRED "; +//pub const AP_CSA_FINISHED = "AP-CSA-FINISHED "; +//pub const P2P_EVENT_LISTEN_OFFLOAD_STOP = "P2P-LISTEN-OFFLOAD-STOPPED "; +//pub const P2P_LISTEN_OFFLOAD_STOP_REASON = "P2P-LISTEN-OFFLOAD-STOP-REASON "; +//pub const BSS_TM_RESP = "BSS-TM-RESP "; +//pub const COLOC_INTF_REQ = "COLOC-INTF-REQ "; +//pub const COLOC_INTF_REPORT = "COLOC-INTF-REPORT "; +//pub const MBO_CELL_PREFERENCE = "MBO-CELL-PREFERENCE "; diff --git a/lib/nif/wpa_supplicant/COPYING b/lib/nif/wpa_supplicant/COPYING new file mode 100644 index 0000000..7ca3030 --- /dev/null +++ b/lib/nif/wpa_supplicant/COPYING @@ -0,0 +1,22 @@ +wpa_supplicant and hostapd +-------------------------- + +Copyright (c) 2002-2022, Jouni Malinen and contributors +All Rights Reserved. + + +See the README file for the current license terms. + +This software was previously distributed under BSD/GPL v2 dual license +terms that allowed either of those license alternatives to be +selected. As of February 11, 2012, the project has chosen to use only +the BSD license option for future distribution. As such, the GPL v2 +license option is no longer used. It should be noted that the BSD +license option (the one with advertisement clause removed) is compatible +with GPL and as such, does not prevent use of this software in projects +that use GPL. + +Some of the files may still include pointers to GPL version 2 license +terms. However, such copyright and license notifications are maintained +only for attribution purposes and any distribution of this software +after February 11, 2012 is no longer under the GPL v2 option. diff --git a/lib/nif/wpa_supplicant/ChangeLog b/lib/nif/wpa_supplicant/ChangeLog new file mode 100644 index 0000000..efcc6cd --- /dev/null +++ b/lib/nif/wpa_supplicant/ChangeLog @@ -0,0 +1,2500 @@ +ChangeLog for wpa_supplicant + +2022-01-16 - v2.10 + * SAE changes + - improved protection against side channel attacks + [https://w1.fi/security/2022-1/] + - added support for the hash-to-element mechanism (sae_pwe=1 or + sae_pwe=2); this is currently disabled by default, but will likely + get enabled by default in the future + - fixed PMKSA caching with OKC + - added support for SAE-PK + * EAP-pwd changes + - improved protection against side channel attacks + [https://w1.fi/security/2022-1/] + * fixed P2P provision discovery processing of a specially constructed + invalid frame + [https://w1.fi/security/2021-1/] + * fixed P2P group information processing of a specially constructed + invalid frame + [https://w1.fi/security/2020-2/] + * fixed PMF disconnection protection bypass in AP mode + [https://w1.fi/security/2019-7/] + * added support for using OpenSSL 3.0 + * increased the maximum number of EAP message exchanges (mainly to + support cases with very large certificates) + * fixed various issues in experimental support for EAP-TEAP peer + * added support for DPP release 2 (Wi-Fi Device Provisioning Protocol) + * a number of MKA/MACsec fixes and extensions + * added support for SAE (WPA3-Personal) AP mode configuration + * added P2P support for EDMG (IEEE 802.11ay) channels + * fixed EAP-FAST peer with TLS GCM/CCM ciphers + * improved throughput estimation and BSS selection + * dropped support for libnl 1.1 + * added support for nl80211 control port for EAPOL frame TX/RX + * fixed OWE key derivation with groups 20 and 21; this breaks backwards + compatibility for these groups while the default group 19 remains + backwards compatible + * added support for Beacon protection + * added support for Extended Key ID for pairwise keys + * removed WEP support from the default build (CONFIG_WEP=y can be used + to enable it, if really needed) + * added a build option to remove TKIP support (CONFIG_NO_TKIP=y) + * added support for Transition Disable mechanism to allow the AP to + automatically disable transition mode to improve security + * extended D-Bus interface + * added support for PASN + * added a file-based backend for external password storage to allow + secret information to be moved away from the main configuration file + without requiring external tools + * added EAP-TLS peer support for TLS 1.3 (disabled by default for now) + * added support for SCS, MSCS, DSCP policy + * changed driver interface selection to default to automatic fallback + to other compiled in options + * a large number of other fixes, cleanup, and extensions + +2019-08-07 - v2.9 + * SAE changes + - disable use of groups using Brainpool curves + - improved protection against side channel attacks + [https://w1.fi/security/2019-6/] + * EAP-pwd changes + - disable use of groups using Brainpool curves + - allow the set of groups to be configured (eap_pwd_groups) + - improved protection against side channel attacks + [https://w1.fi/security/2019-6/] + * fixed FT-EAP initial mobility domain association using PMKSA caching + (disabled by default for backwards compatibility; can be enabled + with ft_eap_pmksa_caching=1) + * fixed a regression in OpenSSL 1.1+ engine loading + * added validation of RSNE in (Re)Association Response frames + * fixed DPP bootstrapping URI parser of channel list + * extended EAP-SIM/AKA fast re-authentication to allow use with FILS + * extended ca_cert_blob to support PEM format + * improved robustness of P2P Action frame scheduling + * added support for EAP-SIM/AKA using anonymous@realm identity + * fixed Hotspot 2.0 credential selection based on roaming consortium + to ignore credentials without a specific EAP method + * added experimental support for EAP-TEAP peer (RFC 7170) + * added experimental support for EAP-TLS peer with TLS v1.3 + * fixed a regression in WMM parameter configuration for a TDLS peer + * fixed a regression in operation with drivers that offload 802.1X + 4-way handshake + * fixed an ECDH operation corner case with OpenSSL + +2019-04-21 - v2.8 + * SAE changes + - added support for SAE Password Identifier + - changed default configuration to enable only groups 19, 20, 21 + (i.e., disable groups 25 and 26) and disable all unsuitable groups + completely based on REVmd changes + - do not regenerate PWE unnecessarily when the AP uses the + anti-clogging token mechanisms + - fixed some association cases where both SAE and FT-SAE were enabled + on both the station and the selected AP + - started to prefer FT-SAE over SAE AKM if both are enabled + - started to prefer FT-SAE over FT-PSK if both are enabled + - fixed FT-SAE when SAE PMKSA caching is used + - reject use of unsuitable groups based on new implementation guidance + in REVmd (allow only FFC groups with prime >= 3072 bits and ECC + groups with prime >= 256) + - minimize timing and memory use differences in PWE derivation + [https://w1.fi/security/2019-1/] (CVE-2019-9494) + * EAP-pwd changes + - minimize timing and memory use differences in PWE derivation + [https://w1.fi/security/2019-2/] (CVE-2019-9495) + - verify server scalar/element + [https://w1.fi/security/2019-4/] (CVE-2019-9499) + - fix message reassembly issue with unexpected fragment + [https://w1.fi/security/2019-5/] + - enforce rand,mask generation rules more strictly + - fix a memory leak in PWE derivation + - disallow ECC groups with a prime under 256 bits (groups 25, 26, and + 27) + * fixed CONFIG_IEEE80211R=y (FT) build without CONFIG_FILS=y + * Hotspot 2.0 changes + - do not indicate release number that is higher than the one + AP supports + - added support for release number 3 + - enable PMF automatically for network profiles created from + credentials + * fixed OWE network profile saving + * fixed DPP network profile saving + * added support for RSN operating channel validation + (CONFIG_OCV=y and network profile parameter ocv=1) + * added Multi-AP backhaul STA support + * fixed build with LibreSSL + * number of MKA/MACsec fixes and extensions + * extended domain_match and domain_suffix_match to allow list of values + * fixed dNSName matching in domain_match and domain_suffix_match when + using wolfSSL + * started to prefer FT-EAP-SHA384 over WPA-EAP-SUITE-B-192 AKM if both + are enabled + * extended nl80211 Connect and external authentication to support + SAE, FT-SAE, FT-EAP-SHA384 + * fixed KEK2 derivation for FILS+FT + * extended client_cert file to allow loading of a chain of PEM + encoded certificates + * extended beacon reporting functionality + * extended D-Bus interface with number of new properties + * fixed a regression in FT-over-DS with mac80211-based drivers + * OpenSSL: allow systemwide policies to be overridden + * extended driver flags indication for separate 802.1X and PSK + 4-way handshake offload capability + * added support for random P2P Device/Interface Address use + * extended PEAP to derive EMSK to enable use with ERP/FILS + * extended WPS to allow SAE configuration to be added automatically + for PSK (wps_cred_add_sae=1) + * removed support for the old D-Bus interface (CONFIG_CTRL_IFACE_DBUS) + * extended domain_match and domain_suffix_match to allow list of values + * added a RSN workaround for misbehaving PMF APs that advertise + IGTK/BIP KeyID using incorrect byte order + * fixed PTK rekeying with FILS and FT + +2018-12-02 - v2.7 + * fixed WPA packet number reuse with replayed messages and key + reinstallation + [https://w1.fi/security/2017-1/] (CVE-2017-13077, CVE-2017-13078, + CVE-2017-13079, CVE-2017-13080, CVE-2017-13081, CVE-2017-13082, + CVE-2017-13086, CVE-2017-13087, CVE-2017-13088) + * fixed unauthenticated EAPOL-Key decryption in wpa_supplicant + [https://w1.fi/security/2018-1/] (CVE-2018-14526) + * added support for FILS (IEEE 802.11ai) shared key authentication + * added support for OWE (Opportunistic Wireless Encryption, RFC 8110; + and transition mode defined by WFA) + * added support for DPP (Wi-Fi Device Provisioning Protocol) + * added support for RSA 3k key case with Suite B 192-bit level + * fixed Suite B PMKSA caching not to update PMKID during each 4-way + handshake + * fixed EAP-pwd pre-processing with PasswordHashHash + * added EAP-pwd client support for salted passwords + * fixed a regression in TDLS prohibited bit validation + * started to use estimated throughput to avoid undesired signal + strength based roaming decision + * MACsec/MKA: + - new macsec_linux driver interface support for the Linux + kernel macsec module + - number of fixes and extensions + * added support for external persistent storage of PMKSA cache + (PMKSA_GET/PMKSA_ADD control interface commands; and + MESH_PMKSA_GET/MESH_PMKSA_SET for the mesh case) + * fixed mesh channel configuration pri/sec switch case + * added support for beacon report + * large number of other fixes, cleanup, and extensions + * added support for randomizing local address for GAS queries + (gas_rand_mac_addr parameter) + * fixed EAP-SIM/AKA/AKA' ext auth cases within TLS tunnel + * added option for using random WPS UUID (auto_uuid=1) + * added SHA256-hash support for OCSP certificate matching + * fixed EAP-AKA' to add AT_KDF into Synchronization-Failure + * fixed a regression in RSN pre-authentication candidate selection + * added option to configure allowed group management cipher suites + (group_mgmt network profile parameter) + * removed all PeerKey functionality + * fixed nl80211 AP and mesh mode configuration regression with + Linux 4.15 and newer + * added ap_isolate configuration option for AP mode + * added support for nl80211 to offload 4-way handshake into the driver + * added support for using wolfSSL cryptographic library + * SAE + - added support for configuring SAE password separately of the + WPA2 PSK/passphrase + - fixed PTK and EAPOL-Key integrity and key-wrap algorithm selection + for SAE; + note: this is not backwards compatible, i.e., both the AP and + station side implementations will need to be update at the same + time to maintain interoperability + - added support for Password Identifier + - fixed FT-SAE PMKID matching + * Hotspot 2.0 + - added support for fetching of Operator Icon Metadata ANQP-element + - added support for Roaming Consortium Selection element + - added support for Terms and Conditions + - added support for OSEN connection in a shared RSN BSS + - added support for fetching Venue URL information + * added support for using OpenSSL 1.1.1 + * FT + - disabled PMKSA caching with FT since it is not fully functional + - added support for SHA384 based AKM + - added support for BIP ciphers BIP-CMAC-256, BIP-GMAC-128, + BIP-GMAC-256 in addition to previously supported BIP-CMAC-128 + - fixed additional IE inclusion in Reassociation Request frame when + using FT protocol + +2016-10-02 - v2.6 + * fixed WNM Sleep Mode processing when PMF is not enabled + [http://w1.fi/security/2015-6/] (CVE-2015-5310) + * fixed EAP-pwd last fragment validation + [http://w1.fi/security/2015-7/] (CVE-2015-5315) + * fixed EAP-pwd unexpected Confirm message processing + [http://w1.fi/security/2015-8/] (CVE-2015-5316) + * fixed WPS configuration update vulnerability with malformed passphrase + [http://w1.fi/security/2016-1/] (CVE-2016-4476) + * fixed configuration update vulnerability with malformed parameters set + over the local control interface + [http://w1.fi/security/2016-1/] (CVE-2016-4477) + * fixed TK configuration to the driver in EAPOL-Key 3/4 retry case + * extended channel switch support for P2P GO + * started to throttle control interface event message bursts to avoid + issues with monitor sockets running out of buffer space + * mesh mode fixes/improvements + - generate proper AID for peer + - enable WMM by default + - add VHT support + - fix PMKID derivation + - improve robustness on various exchanges + - fix peer link counting in reconnect case + - improve mesh joining behavior + - allow DTIM period to be configured + - allow HT to be disabled (disable_ht=1) + - add MESH_PEER_ADD and MESH_PEER_REMOVE commands + - add support for PMKSA caching + - add minimal support for SAE group negotiation + - allow pairwise/group cipher to be configured in the network profile + - use ieee80211w profile parameter to enable/disable PMF and derive + a separate TX IGTK if PMF is enabled instead of using MGTK + incorrectly + - fix AEK and MTK derivation + - remove GTKdata and IGTKdata from Mesh Peering Confirm/Close + - note: these changes are not fully backwards compatible for secure + (RSN) mesh network + * fixed PMKID derivation with SAE + * added support for requesting and fetching arbitrary ANQP-elements + without internal support in wpa_supplicant for the specific element + (anqp[265]= in "BSS " command output) + * P2P + - filter control characters in group client device names to be + consistent with other P2P peer cases + - support VHT 80+80 MHz and 160 MHz + - indicate group completion in P2P Client role after data association + instead of already after the WPS provisioning step + - improve group-join operation to use SSID, if known, to filter BSS + entries + - added optional ssid= argument to P2P_CONNECT for join case + - added P2P_GROUP_MEMBER command to fetch client interface address + * P2PS + - fix follow-on PD Response behavior + - fix PD Response generation for unknown peer + - fix persistent group reporting + - add channel policy to PD Request + - add group SSID to the P2PS-PROV-DONE event + - allow "P2P_CONNECT p2ps" to be used without specifying the + default PIN + * BoringSSL + - support for OCSP stapling + - support building of h20-osu-client + * D-Bus + - add ExpectDisconnect() + - add global config parameters as properties + - add SaveConfig() + - add VendorElemAdd(), VendorElemGet(), VendorElemRem() + * fixed Suite B 192-bit AKM to use proper PMK length + (note: this makes old releases incompatible with the fixed behavior) + * improved PMF behavior for cases where the AP and STA has different + configuration by not trying to connect in some corner cases where the + connection cannot succeed + * added option to reopen debug log (e.g., to rotate the file) upon + receipt of SIGHUP signal + * EAP-pwd: added support for Brainpool Elliptic Curves + (with OpenSSL 1.0.2 and newer) + * fixed EAPOL reauthentication after FT protocol run + * fixed FTIE generation for 4-way handshake after FT protocol run + * extended INTERFACE_ADD command to allow certain type (sta/ap) + interface to be created + * fixed and improved various FST operations + * added 80+80 MHz and 160 MHz VHT support for IBSS/mesh + * fixed SIGNAL_POLL in IBSS and mesh cases + * added an option to abort an ongoing scan (used to speed up connection + and can also be done with the new ABORT_SCAN command) + * TLS client + - do not verify CA certificates when ca_cert is not specified + - support validating server certificate hash + - support SHA384 and SHA512 hashes + - add signature_algorithms extension into ClientHello + - support TLS v1.2 signature algorithm with SHA384 and SHA512 + - support server certificate probing + - allow specific TLS versions to be disabled with phase2 parameter + - support extKeyUsage + - support PKCS #5 v2.0 PBES2 + - support PKCS #5 with PKCS #12 style key decryption + - minimal support for PKCS #12 + - support OCSP stapling (including ocsp_multi) + * OpenSSL + - support OpenSSL 1.1 API changes + - drop support for OpenSSL 0.9.8 + - drop support for OpenSSL 1.0.0 + * added support for multiple schedule scan plans (sched_scan_plans) + * added support for external server certificate chain validation + (tls_ext_cert_check=1 in the network profile phase1 parameter) + * made phase2 parser more strict about correct use of auth= and + autheap= values + * improved GAS offchannel operations with comeback request + * added SIGNAL_MONITOR command to request signal strength monitoring + events + * added command for retrieving HS 2.0 icons with in-memory storage + (REQ_HS20_ICON, GET_HS20_ICON, DEL_HS20_ICON commands and + RX-HS20-ICON event) + * enabled ACS support for AP mode operations with wpa_supplicant + * EAP-PEAP: fixed interoperability issue with Windows 2012r2 server + ("Invalid Compound_MAC in cryptobinding TLV") + * EAP-TTLS: fixed success after fragmented final Phase 2 message + * VHT: added interoperability workaround for 80+80 and 160 MHz channels + * WNM: workaround for broken AP operating class behavior + * added kqueue(2) support for eloop (CONFIG_ELOOP_KQUEUE) + * nl80211: + - add support for full station state operations + - do not add NL80211_ATTR_SMPS_MODE attribute if HT is disabled + - add NL80211_ATTR_PREV_BSSID with Connect command + - fix IEEE 802.1X/WEP EAP reauthentication and rekeying to use + unencrypted EAPOL frames + * added initial MBO support; number of extensions to WNM BSS Transition + Management + * added support for PBSS/PCP and P2P on 60 GHz + * Interworking: add credential realm to EAP-TLS identity + * fixed EAPOL-Key Request Secure bit to be 1 if PTK is set + * HS 2.0: add support for configuring frame filters + * added POLL_STA command to check connectivity in AP mode + * added initial functionality for location related operations + * started to ignore pmf=1/2 parameter for non-RSN networks + * added wps_disabled=1 network profile parameter to allow AP mode to + be started without enabling WPS + * wpa_cli: added action script support for AP-ENABLED and AP-DISABLED + events + * improved Public Action frame addressing + - add gas_address3 configuration parameter to control Address 3 + behavior + * number of small fixes + +2015-09-27 - v2.5 + * fixed P2P validation of SSID element length before copying it + [http://w1.fi/security/2015-1/] (CVE-2015-1863) + * fixed WPS UPnP vulnerability with HTTP chunked transfer encoding + [http://w1.fi/security/2015-2/] (CVE-2015-4141) + * fixed WMM Action frame parser (AP mode) + [http://w1.fi/security/2015-3/] (CVE-2015-4142) + * fixed EAP-pwd peer missing payload length validation + [http://w1.fi/security/2015-4/] + (CVE-2015-4143, CVE-2015-4144, CVE-2015-4145, CVE-2015-4146) + * fixed validation of WPS and P2P NFC NDEF record payload length + [http://w1.fi/security/2015-5/] + * nl80211: + - added VHT configuration for IBSS + - fixed vendor command handling to check OUI properly + - allow driver-based roaming to change ESS + * added AVG_BEACON_RSSI to SIGNAL_POLL output + * wpa_cli: added tab completion for number of commands + * removed unmaintained and not yet completed SChannel/CryptoAPI support + * modified Extended Capabilities element use in Probe Request frames to + include all cases if any of the values are non-zero + * added support for dynamically creating/removing a virtual interface + with interface_add/interface_remove + * added support for hashed password (NtHash) in EAP-pwd peer + * added support for memory-only PSK/passphrase (mem_only_psk=1 and + CTRL-REQ/RSP-PSK_PASSPHRASE) + * P2P + - optimize scan frequencies list when re-joining a persistent group + - fixed number of sequences with nl80211 P2P Device interface + - added operating class 125 for P2P use cases (this allows 5 GHz + channels 161 and 169 to be used if they are enabled in the current + regulatory domain) + - number of fixes to P2PS functionality + - do not allow 40 MHz co-ex PRI/SEC switch to force MCC + - extended support for preferred channel listing + * D-Bus: + - fixed WPS property of fi.w1.wpa_supplicant1.BSS interface + - fixed PresenceRequest to use group interface + - added new signals: FindStopped, WPS pbc-overlap, + GroupFormationFailure, WPS timeout, InvitationReceived + - added new methods: WPS Cancel, P2P Cancel, Reconnect, RemoveClient + - added manufacturer info + * added EAP-EKE peer support for deriving Session-Id + * added wps_priority configuration parameter to set the default priority + for all network profiles added by WPS + * added support to request a scan with specific SSIDs with the SCAN + command (optional "ssid " arguments) + * removed support for WEP40/WEP104 as a group cipher with WPA/WPA2 + * fixed SAE group selection in an error case + * modified SAE routines to be more robust and PWE generation to be + stronger against timing attacks + * added support for Brainpool Elliptic Curves with SAE + * added support for CCMP-256 and GCMP-256 as group ciphers with FT + * fixed BSS selection based on estimated throughput + * added option to disable TLSv1.0 with OpenSSL + (phase1="tls_disable_tlsv1_0=1") + * added Fast Session Transfer (FST) module + * fixed OpenSSL PKCS#12 extra certificate handling + * fixed key derivation for Suite B 192-bit AKM (this breaks + compatibility with the earlier version) + * added RSN IE to Mesh Peering Open/Confirm frames + * number of small fixes + +2015-03-15 - v2.4 + * allow OpenSSL cipher configuration to be set for internal EAP server + (openssl_ciphers parameter) + * fixed number of small issues based on hwsim test case failures and + static analyzer reports + * P2P: + - add new=<0/1> flag to P2P-DEVICE-FOUND events + - add passive channels in invitation response from P2P Client + - enable nl80211 P2P_DEVICE support by default + - fix regresssion in disallow_freq preventing search on social + channels + - fix regressions in P2P SD query processing + - try to re-invite with social operating channel if no common channels + in invitation + - allow cross connection on parent interface (this fixes number of + use cases with nl80211) + - add support for P2P services (P2PS) + - add p2p_go_ctwindow configuration parameter to allow GO CTWindow to + be configured + * increase postponing of EAPOL-Start by one second with AP/GO that + supports WPS 2.0 (this makes it less likely to trigger extra roundtrip + of identity frames) + * add support for PMKSA caching with SAE + * add support for control mesh BSS (IEEE 802.11s) operations + * fixed number of issues with D-Bus P2P commands + * fixed regression in ap_scan=2 special case for WPS + * fixed macsec_validate configuration + * add a workaround for incorrectly behaving APs that try to use + EAPOL-Key descriptor version 3 when the station supports PMF even if + PMF is not enabled on the AP + * allow TLS v1.1 and v1.2 to be negotiated by default; previous behavior + of disabling these can be configured to work around issues with broken + servers with phase1="tls_disable_tlsv1_1=1 tls_disable_tlsv1_2=1" + * add support for Suite B (128-bit and 192-bit level) key management and + cipher suites + * add WMM-AC support (WMM_AC_ADDTS/WMM_AC_DELTS) + * improved BSS Transition Management processing + * add support for neighbor report + * add support for link measurement + * fixed expiration of BSS entry with all-zeros BSSID + * add optional LAST_ID=x argument to LIST_NETWORK to allow all + configured networks to be listed even with huge number of network + profiles + * add support for EAP Re-Authentication Protocol (ERP) + * fixed EAP-IKEv2 fragmentation reassembly + * improved PKCS#11 configuration for OpenSSL + * set stdout to be line-buffered + * add TDLS channel switch configuration + * add support for MAC address randomization in scans with nl80211 + * enable HT for IBSS if supported by the driver + * add BSSID black and white lists (bssid_blacklist, bssid_whitelist) + * add support for domain_suffix_match with GnuTLS + * add OCSP stapling client support with GnuTLS + * include peer certificate in EAP events even without a separate probe + operation; old behavior can be restored with cert_in_cb=0 + * add peer ceritficate alt subject name to EAP events + (CTRL-EVENT-EAP-PEER-ALT) + * add domain_match network profile parameter (similar to + domain_suffix_match, but full match is required) + * enable AP/GO mode HT Tx STBC automatically based on driver support + * add ANQP-QUERY-DONE event to provide information on ANQP parsing + status + * allow passive scanning to be forced with passive_scan=1 + * add a workaround for Linux packet socket behavior when interface is in + bridge + * increase 5 GHz band preference in BSS selection (estimate SNR, if info + not available from driver; estimate maximum throughput based on common + HT/VHT/specific TX rate support) + * add INTERWORKING_ADD_NETWORK ctrl_iface command; this can be used to + implement Interworking network selection behavior in upper layers + software components + * add optional reassoc_same_bss_optim=1 (disabled by default) + optimization to avoid unnecessary Authentication frame exchange + * extend TDLS frame padding workaround to cover all packets + * allow wpa_supplicant to recover nl80211 functionality if the cfg80211 + module gets removed and reloaded without restarting wpa_supplicant + * allow hostapd DFS implementation to be used in wpa_supplicant AP mode + +2014-10-09 - v2.3 + * fixed number of minor issues identified in static analyzer warnings + * fixed wfd_dev_info to be more careful and not read beyond the buffer + when parsing invalid information for P2P-DEVICE-FOUND + * extended P2P and GAS query operations to support drivers that have + maximum remain-on-channel time below 1000 ms (500 ms is the current + minimum supported value) + * added p2p_search_delay parameter to make the default p2p_find delay + configurable + * improved P2P operating channel selection for various multi-channel + concurrency cases + * fixed some TDLS failure cases to clean up driver state + * fixed dynamic interface addition cases with nl80211 to avoid adding + ifindex values to incorrect interface to skip foreign interface events + properly + * added TDLS workaround for some APs that may add extra data to the + end of a short frame + * fixed EAP-AKA' message parser with multiple AT_KDF attributes + * added configuration option (p2p_passphrase_len) to allow longer + passphrases to be generated for P2P groups + * fixed IBSS channel configuration in some corner cases + * improved HT/VHT/QoS parameter setup for TDLS + * modified D-Bus interface for P2P peers/groups + * started to use constant time comparison for various password and hash + values to reduce possibility of any externally measurable timing + differences + * extended explicit clearing of freed memory and expired keys to avoid + keeping private data in memory longer than necessary + * added optional scan_id parameter to the SCAN command to allow manual + scan requests for active scans for specific configured SSIDs + * fixed CTRL-EVENT-REGDOM-CHANGE event init parameter value + * added option to set Hotspot 2.0 Rel 2 update_identifier in network + configuration to support external configuration + * modified Android PNO functionality to send Probe Request frames only + for hidden SSIDs (based on scan_ssid=1) + * added generic mechanism for adding vendor elements into frames at + runtime (VENDOR_ELEM_ADD, VENDOR_ELEM_GET, VENDOR_ELEM_REMOVE) + * added fields to show unrecognized vendor elements in P2P_PEER + * removed EAP-TTLS/MSCHAPv2 interoperability workaround so that + MS-CHAP2-Success is required to be present regardless of + eap_workaround configuration + * modified EAP fast session resumption to allow results to be used only + with the same network block that generated them + * extended freq_list configuration to apply for sched_scan as well as + normal scan + * modified WPS to merge mixed-WPA/WPA2 credentials from a single session + * fixed nl80211/RTM_DELLINK processing when a P2P GO interface is + removed from a bridge + * fixed number of small P2P issues to make negotiations more robust in + corner cases + * added experimental support for using temporary, random local MAC + address (mac_addr and preassoc_mac_addr parameters); this is disabled + by default (i.e., previous behavior of using permanent address is + maintained if configuration is not changed) + * added D-Bus interface for setting/clearing WFD IEs + * fixed TDLS AID configuration for VHT + * modified -m configuration file to be used only for the P2P + non-netdev management device and do not load this for the default + station interface or load the station interface configuration for + the P2P management interface + * fixed external MAC address changes while wpa_supplicant is running + * started to enable HT (if supported by the driver) for IBSS + * fixed wpa_cli action script execution to use more robust mechanism + (CVE-2014-3686) + +2014-06-04 - v2.2 + * added DFS indicator to get_capability freq + * added/fixed nl80211 functionality + - BSSID/frequency hint for driver-based BSS selection + - fix tearing down WDS STA interfaces + - support vendor specific driver command + (VENDOR []) + - GO interface teardown optimization + - allow beacon interval to be configured for IBSS + - add SHA256-based AKM suites to CONNECT/ASSOCIATE commands + * removed unused NFC_RX_HANDOVER_REQ and NFC_RX_HANDOVER_SEL control + interface commands (the more generic NFC_REPORT_HANDOVER is now used) + * fixed MSCHAP UTF-8 to UCS-2 conversion for three-byte encoding; + this fixes password with include UTF-8 characters that use + three-byte encoding EAP methods that use NtPasswordHash + * fixed couple of sequences where radio work items could get stuck, + e.g., when rfkill blocking happens during scanning or when + scan-for-auth workaround is used + * P2P enhancements/fixes + - enable enable U-APSD on GO automatically if the driver indicates + support for this + - fixed some service discovery cases with broadcast queries not being + sent to all stations + - fixed Probe Request frame triggering invitation to trigger only a + single invitation instance even if multiple Probe Request frames are + received + - fixed a potential NULL pointer dereference crash when processing an + invalid Invitation Request frame + - add optional configuration file for the P2P_DEVICE parameters + - optimize scan for GO during persistent group invocation + - fix possible segmentation fault when PBC overlap is detected while + using a separate P2P group interface + - improve GO Negotiation robustness by allowing GO Negotiation + Confirmation to be retransmitted + - do use freed memory on device found event when P2P NFC + * added phase1 network parameter options for disabling TLS v1.1 and v1.2 + to allow workarounds with misbehaving AAA servers + (tls_disable_tlsv1_1=1 and tls_disable_tlsv1_2=1) + * added support for OCSP stapling to validate AAA server certificate + during TLS exchange + * Interworking/Hotspot 2.0 enhancements + - prefer the last added network in Interworking connection to make the + behavior more consistent with likely user expectation + - roaming partner configuration (roaming_partner within a cred block) + - support Hotspot 2.0 Release 2 + * "hs20_anqp_get 8" to request OSU Providers list + * "hs20_icon_request " to request icon files + * "fetch_osu" and "cancel_osu_fetch" to start/stop full OSU provider + search (all suitable APs in scan results) + * OSEN network for online signup connection + * min_{dl,ul}_bandwidth_{home,roaming} cred parameters + * max_bss_load cred parameter + * req_conn_capab cred parameter + * sp_priority cred parameter + * ocsp cred parameter + * slow down automatic connection attempts on EAP failure to meet + required behavior (no more than 10 retries within a 10-minute + interval) + * sample implementation of online signup client (both SPP and + OMA-DM protocols) (hs20/client/*) + - fixed GAS indication for additional comeback delay with status + code 95 + - extend ANQP_GET to accept Hotspot 2.0 subtypes + ANQP_GET [,]... + [,hs20:][...,hs20:] + - add control interface events CRED-ADDED , + CRED-MODIFIED , CRED-REMOVED + - add "GET_CRED " command + - enable FT for the connection automatically if the AP advertises + support for this + - fix a case where auto_interworking=1 could end up stopping scanning + * fixed TDLS interoperability issues with supported operating class in + some deployed stations + * internal TLS implementation enhancements/fixes + - add SHA256-based cipher suites + - add DHE-RSA cipher suites + - fix X.509 validation of PKCS#1 signature to check for extra data + * fixed PTK derivation for CCMP-256 and GCMP-256 + * added "reattach" command for fast reassociate-back-to-same-BSS + * allow PMF to be enabled for AP mode operation with the ieee80211w + parameter + * added "get_capability tdls" command + * added option to set config blobs through control interface with + "SET blob " + * D-Bus interface extensions/fixes + - make p2p_no_group_iface configurable + - declare ServiceDiscoveryRequest method properly + - export peer's device address as a property + - make reassociate command behave like the control interface one, + i.e., to allow connection from disconnected state + * added optional "freq=" parameter to SET pno + * added optional "freq=" parameter to SELECT_NETWORK + * fixed OBSS scan result processing for 20/40 MHz co-ex report + * remove WPS 1.0 only support, i.e., WSC 2.0 support is now enabled + whenever CONFIG_WPS=y is set + * fixed regression in parsing of WNM Sleep Mode exit key data + * fixed potential segmentation fault and memory leaks in WNM neighbor + report processing + * EAP-pwd fixes + - fragmentation of PWD-Confirm-Resp + - fix memory leak when fragmentation is used + - fix possible segmentation fault on EAP method deinit if an invalid + group is negotiated + * added MACsec/IEEE Std 802.1X-2010 PAE implementation (currently + available only with the macsec_qca driver wrapper) + * fixed EAP-SIM counter-too-small message + * added 'dup_network ' command; this can be used to + clone the psk field without having toextract it from wpa_supplicant + * fixed GSM authentication on USIM + * added support for using epoll in eloop (CONFIG_ELOOP_EPOLL=y) + * fixed some concurrent virtual interface cases with dedicated P2P + management interface to not catch events from removed interface (this + could result in the management interface getting disabled) + * fixed a memory leak in SAE random number generation + * fixed off-by-one bounds checking in printf_encode() + - this could result in some control interface ATTACH command cases + terminating wpa_supplicant + * fixed EAPOL-Key exchange when GCMP is used with SHA256-based AKM + * various bug fixes + +2014-02-04 - v2.1 + * added support for simultaneous authentication of equals (SAE) for + stronger password-based authentication with WPA2-Personal + * improved P2P negotiation and group formation robustness + - avoid unnecessary Dialog Token value changes during retries + - avoid more concurrent scanning cases during full group formation + sequence + - do not use potentially obsolete scan result data from driver + cache for peer discovery/updates + - avoid undesired re-starting of GO negotiation based on Probe + Request frames + - increase GO Negotiation and Invitation timeouts to address busy + environments and peers that take long time to react to messages, + e.g., due to power saving + - P2P Device interface type + * improved P2P channel selection (use more peer information and allow + more local options) + * added support for optional per-device PSK assignment by P2P GO + (wpa_cli p2p_set per_sta_psk <0/1>) + * added P2P_REMOVE_CLIENT for removing a client from P2P groups + (including persistent groups); this can be used to securely remove + a client from a group if per-device PSKs are used + * added more configuration flexibility for allowed P2P GO/client + channels (p2p_no_go_freq list and p2p_add_cli_chan=0/1) + * added nl80211 functionality + - VHT configuration for nl80211 + - MFP (IEEE 802.11w) information for nl80211 command API + - support split wiphy dump + - FT (IEEE 802.11r) with driver-based SME + - use advertised number of supported concurrent channels + - QoS Mapping configuration + * improved TDLS negotiation robustness + * added more TDLS peer parameters to be configured to the driver + * optimized connection time by allowing recently received scan results + to be used instead of having to run through a new scan + * fixed ctrl_iface BSS command iteration with RANGE argument and no + exact matches; also fixed argument parsing for some cases with + multiple arguments + * added 'SCAN TYPE=ONLY' ctrl_iface command to request manual scan + without executing roaming/network re-selection on scan results + * added Session-Id derivation for EAP peer methods + * added fully automated regression testing with mac80211_hwsim + * changed configuration parser to reject invalid integer values + * allow AP/Enrollee to be specified with BSSID instead of UUID for + WPS ER operations + * disable network block temporarily on repeated connection failures + * changed the default driver interface from wext to nl80211 if both are + included in the build + * remove duplicate networks if WPS provisioning is run multiple times + * remove duplicate networks when Interworking network selection uses the + same network + * added global freq_list configuration to allow scan frequencies to be + limited for all cases instead of just for a specific network block + * added support for BSS Transition Management + * added option to use "IFNAME= " prefix to use the global + control interface connection to perform per-interface commands; + similarly, allow global control interface to be used as a monitor + interface to receive events from all interfaces + * fixed OKC-based PMKSA cache entry clearing + * fixed TKIP group key configuration with FT + * added support for using OCSP stapling to validate server certificate + (ocsp=1 as optional and ocsp=2 as mandatory) + * added EAP-EKE peer + * added peer restart detection for IBSS RSN + * added domain_suffix_match (and domain_suffix_match2 for Phase 2 + EAP-TLS) to specify additional constraint for the server certificate + domain name + * added support for external SIM/USIM processing in EAP-SIM, EAP-AKA, + and EAP-AKA' (CTRL-REQ-SIM and CTRL-RSP-SIM commands over control + interface) + * added global bgscan configuration option as a default for all network + blocks that do not specify their own bgscan parameters + * added D-Bus methods for TDLS + * added more control to scan requests + - "SCAN freq=" can be used to specify which channels are + scanned (comma-separated frequency ranges in MHz) + - "SCAN passive=1" can be used to request a passive scan (no Probe + Request frames are sent) + - "SCAN use_id" can be used to request a scan id to be returned and + included in event messages related to this specific scan operation + - "SCAN only_new=1" can be used to request the driver/cfg80211 to + report only BSS entries that have been updated during this scan + round + - these optional arguments to the SCAN command can be combined with + each other + * modified behavior on externally triggered scans + - avoid concurrent operations requiring full control of the radio when + an externally triggered scan is detected + - do not use results for internal roaming decision + * added a new cred block parameter 'temporary' to allow credential + blocks to be stored separately even if wpa_supplicant configuration + file is used to maintain other network information + * added "radio work" framework to schedule exclusive radio operations + for off-channel functionality + - reduce issues with concurrent operations that try to control which + channel is used + - allow external programs to request exclusive radio control in a way + that avoids conflicts with wpa_supplicant + * added support for using Protected Dual of Public Action frames for + GAS/ANQP exchanges when associated with PMF + * added support for WPS+NFC updates and P2P+NFC + - improved protocol for WPS + - P2P group formation/join based on NFC connection handover + - new IPv4 address assignment for P2P groups (ip_addr_* configuration + parameters on the GO) to replace DHCP + - option to fetch and report alternative carrier records for external + NFC operations + * various bug fixes + +2013-01-12 - v2.0 + * removed Qt3-based wpa_gui (obsoleted by wpa_qui-qt4) + * removed unmaintained driver wrappers broadcom, iphone, osx, ralink, + hostap, madwifi (hostap and madwifi remain available for hostapd; + their wpa_supplicant functionality is obsoleted by wext) + * improved debug logging (human readable event names, interface name + included in more entries) + * changed AP mode behavior to enable WPS only for open and + WPA/WPA2-Personal configuration + * improved P2P concurrency operations + - better coordination of concurrent scan and P2P search operations + - avoid concurrent remain-on-channel operation requests by canceling + previous operations prior to starting a new one + - reject operations that would require multi-channel concurrency if + the driver does not support it + - add parameter to select whether STA or P2P connection is preferred + if the driver cannot support both at the same time + - allow driver to indicate channel changes + - added optional delay= parameter for + p2p_find to avoid taking all radio resources + - use 500 ms p2p_find search delay by default during concurrent + operations + - allow all channels in GO Negotiation if the driver supports + multi-channel concurrency + * added number of small changes to make it easier for static analyzers + to understand the implementation + * fixed number of small bugs (see git logs for more details) + * nl80211: number of updates to use new cfg80211/nl80211 functionality + - replace monitor interface with nl80211 commands for AP mode + - additional information for driver-based AP SME + - STA entry authorization in RSN IBSS + * EAP-pwd: + - fixed KDF for group 21 and zero-padding + - added support for fragmentation + - increased maximum number of hunting-and-pecking iterations + * avoid excessive Probe Response retries for broadcast Probe Request + frames (only with drivers using wpa_supplicant AP mode SME/MLME) + * added "GET country" ctrl_iface command + * do not save an invalid network block in wpa_supplicant.conf to avoid + problems reading the file on next start + * send STA connected/disconnected ctrl_iface events to both the P2P + group and parent interfaces + * added preliminary support for using TLS v1.2 (CONFIG_TLSV12=y) + * added "SET pno <1/0>" ctrl_iface command to start/stop preferred + network offload with sched_scan driver command + * merged in number of changes from Android repository for P2P, nl80211, + and build parameters + * changed P2P GO mode configuration to use driver capabilities to + automatically enable HT operations when supported + * added "wpa_cli status wps" command to fetch WPA2-Personal passhrase + for WPS use cases in AP mode + * EAP-AKA: keep pseudonym identity across EAP exchanges to match EAP-SIM + behavior + * improved reassociation behavior in cases where association is rejected + or when an AP disconnects us to handle common load balancing + mechanisms + - try to avoid extra scans when the needed information is available + * added optional "join" argument for p2p_prov_disc ctrl_iface command + * added group ifname to P2P-PROV-DISC-* events + * added P2P Device Address to AP-STA-DISCONNECTED event and use + p2p_dev_addr parameter name with AP-STA-CONNECTED + * added workarounds for WPS PBC overlap detection for some P2P use cases + where deployed stations work incorrectly + * optimize WPS connection speed by disconnecting prior to WPS scan and + by using single channel scans when AP channel is known + * PCSC and SIM/USIM improvements: + - accept 0x67 (Wrong length) as a response to READ RECORD to fix + issues with some USIM cards + - try to read MNC length from SIM/USIM + - build realm according to 3GPP TS 23.003 with identity from the SIM + - allow T1 protocol to be enabled + * added more WPS and P2P information available through D-Bus + * improve P2P negotiation robustness + - extra waits to get ACK frames through + - longer timeouts for cases where deployed devices have been + identified have issues meeting the specification requirements + - more retries for some P2P frames + - handle race conditions in GO Negotiation start by both devices + - ignore unexpected GO Negotiation Response frame + * added support for libnl 3.2 and newer + * added P2P persistent group info to P2P_PEER data + * maintain a list of P2P Clients for persistent group on GO + * AP: increased initial group key handshake retransmit timeout to 500 ms + * added optional dev_id parameter for p2p_find + * added P2P-FIND-STOPPED ctrl_iface event + * fixed issues in WPA/RSN element validation when roaming with ap_scan=1 + and driver-based BSS selection + * do not expire P2P peer entries while connected with the peer in a + group + * fixed WSC element inclusion in cases where P2P is disabled + * AP: added a WPS workaround for mixed mode AP Settings with Windows 7 + * EAP-SIM: fixed AT_COUNTER_TOO_SMALL use + * EAP-SIM/AKA: append realm to pseudonym identity + * EAP-SIM/AKA: store pseudonym identity in network configuration to + allow it to persist over multiple EAP sessions and wpa_supplicant + restarts + * EAP-AKA': updated to RFC 5448 (username prefixes changed); note: this + breaks interoperability with older versions + * added support for WFA Hotspot 2.0 + - GAS/ANQP to fetch network information + - credential configuration and automatic network selections based on + credential match with ANQP information + * limited PMKSA cache entries to be used only with the network context + that was used to create them + * improved PMKSA cache expiration to avoid unnecessary disconnections + * adjusted bgscan_simple fast-scan backoff to avoid too frequent + background scans + * removed ctrl_iface event on P2P PD Response in join-group case + * added option to fetch BSS table entry based on P2P Device Address + ("BSS p2p_dev_addr=") + * added BSS entry age to ctrl_iface BSS command output + * added optional MASK=0xH option for ctrl_iface BSS command to select + which fields are included in the response + * added optional RANGE=ALL|N1-N2 option for ctrl_iface BSS command to + fetch information about several BSSes in one call + * simplified licensing terms by selecting the BSD license as the only + alternative + * added "P2P_SET disallow_freq " ctrl_iface command to + disable channels from P2P use + * added p2p_pref_chan configuration parameter to allow preferred P2P + channels to be specified + * added support for advertising immediate availability of a WPS + credential for P2P use cases + * optimized scan operations for P2P use cases (use single channel scan + for a specific SSID when possible) + * EAP-TTLS: fixed peer challenge generation for MSCHAPv2 + * SME: do not use reassociation after explicit disconnection request + (local or a notification from an AP) + * added support for sending debug info to Linux tracing (-T on command + line) + * added support for using Deauthentication reason code 3 as an + indication of P2P group termination + * added wps_vendor_ext_m1 configuration parameter to allow vendor + specific attributes to be added to WPS M1 + * started using separate TLS library context for tunneled TLS + (EAP-PEAP/TLS, EAP-TTLS/TLS, EAP-FAST/TLS) to support different CA + certificate configuration between Phase 1 and Phase 2 + * added optional "auto" parameter for p2p_connect to request automatic + GO Negotiation vs. join-a-group selection + * added disabled_scan_offload parameter to disable automatic scan + offloading (sched_scan) + * added optional persistent= parameter for p2p_connect to + allow forcing of a specific SSID/passphrase for GO Negotiation + * added support for OBSS scan requests and 20/40 BSS coexistence reports + * reject PD Request for unknown group + * removed scripts and notes related to Windows binary releases (which + have not been used starting from 1.x) + * added initial support for WNM operations + - Keep-alive based on BSS max idle period + - WNM-Sleep Mode + - minimal BSS Transition Management processing + * added autoscan module to control scanning behavior while not connected + - autoscan_periodic and autoscan_exponential modules + * added new WPS NFC ctrl_iface mechanism + - added initial support NFC connection handover + - removed obsoleted WPS_OOB command (including support for deprecated + UFD config_method) + * added optional framework for external password storage ("ext:") + * wpa_cli: added optional support for controlling wpa_supplicant + remotely over UDP (CONFIG_CTRL_IFACE=udp-remote) for testing purposes + * wpa_cli: extended tab completion to more commands + * changed SSID output to use printf-escaped strings instead of masking + of non-ASCII characters + - SSID can now be configured in the same format: ssid=P"abc\x00test" + * removed default ACM=1 from AC_VO and AC_VI + * added optional "ht40" argument for P2P ctrl_iface commands to allow + 40 MHz channels to be requested on the 5 GHz band + * added optional parameters for p2p_invite command to specify channel + when reinvoking a persistent group as the GO + * improved FIPS mode builds with OpenSSL + - "make fips" with CONFIG_FIPS=y to build wpa_supplicant with the + OpenSSL FIPS object module + - replace low level OpenSSL AES API calls to use EVP + - use OpenSSL keying material exporter when possible + - do not export TLS keys in FIPS mode + - remove MD5 from CONFIG_FIPS=y builds + - use OpenSSL function for PKBDF2 passphrase-to-PSK + - use OpenSSL HMAC implementation + - mix RAND_bytes() output into random_get_bytes() to force OpenSSL + DRBG to be used in FIPS mode + - use OpenSSL CMAC implementation + * added mechanism to disable TLS Session Ticket extension + - a workaround for servers that do not support TLS extensions that + was enabled by default in recent OpenSSL versions + - tls_disable_session_ticket=1 + - automatically disable TLS Session Ticket extension by default when + using EAP-TLS/PEAP/TTLS (i.e., only use it with EAP-FAST) + * changed VENDOR-TEST EAP method to use proper private enterprise number + (this will not interoperate with older versions) + * disable network block temporarily on authentication failures + * improved WPS AP selection during WPS PIN iteration + * added support for configuring GCMP cipher for IEEE 802.11ad + * added support for Wi-Fi Display extensions + - WFD_SUBELEMENT_SET ctrl_iface command to configure WFD subelements + - SET wifi_display <0/1> to disable/enable WFD support + - WFD service discovery + - an external program is needed to manage the audio/video streaming + and codecs + * optimized scan result use for network selection + - use the internal BSS table instead of raw scan results + - allow unnecessary scans to be skipped if fresh information is + available (e.g., after GAS/ANQP round for Interworking) + * added support for 256-bit AES with internal TLS implementation + * allow peer to propose channel in P2P invitation process for a + persistent group + * added disallow_aps parameter to allow BSSIDs/SSIDs to be disallowed + from network selection + * re-enable the networks disabled during WPS operations + * allow P2P functionality to be disabled per interface (p2p_disabled=1) + * added secondary device types into P2P_PEER output + * added an option to disable use of a separate P2P group interface + (p2p_no_group_iface=1) + * fixed P2P Bonjour SD to match entries with both compressed and not + compressed domain name format and support multiple Bonjour PTR matches + for the same key + * use deauthentication instead of disassociation for all disconnection + operations; this removes the now unused disassociate() wpa_driver_ops + callback + * optimized PSK generation on P2P GO by caching results to avoid + multiple PBKDF2 operations + * added okc=1 global configuration parameter to allow OKC to be enabled + by default for all network blocks + * added a workaround for WPS PBC session overlap detection to avoid + interop issues with deployed station implementations that do not + remove active PBC indication from Probe Request frames properly + * added basic support for 60 GHz band + * extend EAPOL frames processing workaround for roaming cases + (postpone processing of unexpected EAPOL frame until association + event to handle reordered events) + +2012-05-10 - v1.0 + * bsd: Add support for setting HT values in IFM_MMASK. + * Delay STA entry removal until Deauth/Disassoc TX status in AP mode. + This allows the driver to use PS buffering of Deauthentication and + Disassociation frames when the STA is in power save sleep. Only + available with drivers that provide TX status events for Deauth/ + Disassoc frames (nl80211). + * Drop oldest unknown BSS table entries first. This makes it less + likely to hit connection issues in environments with huge number + of visible APs. + * Add systemd support. + * Add support for setting the syslog facility from the config file + at build time. + * atheros: Add support for IEEE 802.11w configuration. + * AP mode: Allow enable HT20 if driver supports it, by setting the + config parameter ieee80211n. + * Allow AP mode to disconnect STAs based on low ACK condition (when + the data connection is not working properly, e.g., due to the STA + going outside the range of the AP). Disabled by default, enable by + config option disassoc_low_ack. + * nl80211: + - Support GTK rekey offload. + - Support PMKSA candidate events. This adds support for RSN + pre-authentication with nl80211 interface and drivers that handle + roaming internally. + * dbus: + - Add a DBus signal for EAP SM requests, emitted on the Interface + object. + - Export max scan ssids supported by the driver as MaxScanSSID. + - Add signal Certification for information about server certification. + - Add BSSExpireAge and BSSExpireCount interface properties and + support set/get, which allows for setting BSS cache expiration age + and expiration scan count. + - Add ConfigFile to AddInterface properties. + - Add Interface.Country property and support to get/set the value. + - Add DBus property CurrentAuthMode. + - P2P DBus API added. + - Emit property changed events (for property BSSs) when adding/ + removing BSSs. + - Treat '' in SSIDs of Interface.Scan as a request for broadcast + scan, instead of ignoring it. + - Add DBus getter/setter for FastReauth. + - Raise PropertiesChanged on org.freedesktop.DBus.Properties. + * wpa_cli: + - Send AP-STA-DISCONNECTED event when an AP disconnects a station + due to inactivity. + - Make second argument to set command optional. This can be used to + indicate a zero length value. + - Add signal_poll command. + - Add bss_expire_age and bss_expire_count commands to set/get BSS + cache expiration age and expiration scan count. + - Add ability to set scan interval (the time in seconds wpa_s waits + before requesting a new scan after failing to find a suitable + network in scan results) using scan_interval command. + - Add event CTRL-EVENT-ASSOC-REJECT for association rejected. + - Add command get version, that returns wpa_supplicant version string. + - Add command sta_autoconnect for disabling automatic reconnection + on receiving disconnection event. + - Setting bssid parameter to an empty string "" or any can now be + used to clear the bssid_set flag in a network block, i.e., to remove + bssid filtering. + - Add tdls_testing command to add a special testing feature for + changing TDLS behavior. Build param CONFIG_TDLS_TESTING must be + enabled as well. + - For interworking, add wpa_cli commands interworking_select, + interworking_connect, anqp_get, fetch_anqp, and stop_fetch_anqp. + - Many P2P commands were added. See README-P2P. + - Many WPS/WPS ER commands - see WPS/WPS ER sections for details. + - Allow set command to change global config parameters. + - Add log_level command, which can be used to display the current + debugging level and to change the log level during run time. + - Add note command, which can be used to insert notes to the debug + log. + - Add internal line edit implementation. CONFIG_WPA_CLI_EDIT=y + can now be used to build wpa_cli with internal implementation of + line editing and history support. This can be used as a replacement + for CONFIG_READLINE=y. + * AP mode: Add max_num_sta config option, which can be used to limit + the number of stations allowed to connect to the AP. + * Add WPA_IGNORE_CONFIG_ERRORS build option to continue in case of bad + config file. + * wext: Increase scan timeout from 5 to 10 seconds. + * Add blacklist command, allowing an external program to + manage the BSS blacklist and display its current contents. + * WPS: + - Add wpa_cli wps_pin get command for generating random PINs. This can + be used in a UI to generate a PIN without starting WPS (or P2P) + operation. + - Set RF bands based on driver capabilities, instead of hardcoding + them. + - Add mechanism for indicating non-standard WPS errors. + - Add CONFIG_WPS_REG_DISABLE_OPEN=y option to disable open networks + by default. + - Add wps_ap_pin cli command for wpa_supplicant AP mode. + - Add wps_check_pin cli command for processing PIN from user input. + UIs can use this command to process a PIN entered by a user and to + validate the checksum digit (if present). + - Cancel WPS operation on PBC session overlap detection. + - New wps_cancel command in wpa_cli will cancel a pending WPS + operation. + - wpa_cli action: Add WPS_EVENT_SUCCESS and WPS_EVENT_FAIL handlers. + - Trigger WPS config update on Manufacturer, Model Name, Model + Number, and Serial Number changes. + - Fragment size is now configurable for EAP-WSC peer. Use + wpa_cli set wps_fragment_size . + - Disable AP PIN after 10 consecutive failures. Slow down attacks on + failures up to 10. + - Allow AP to start in Enrollee mode without AP PIN for probing, to + be compatible with Windows 7. + - Add Config Error into WPS-FAIL events to provide more info to the + user on how to resolve the issue. + - Label and Display config methods are not allowed to be enabled + at the same time, since it is unclear which PIN to use if both + methods are advertised. + - When controlling multiple interfaces: + - apply WPS commands to all interfaces configured to use WPS + - apply WPS config changes to all interfaces that use WPS + - when an attack is detected on any interface, disable AP PIN on + all interfaces + * WPS ER: + - Add special AP Setup Locked mode to allow read only ER. + ap_setup_locked=2 can now be used to enable a special mode where + WPS ER can learn the current AP settings, but cannot change them. + - Show SetSelectedRegistrar events as ctrl_iface events + - Add wps_er_set_config to enroll a network based on a local + network configuration block instead of having to (re-)learn the + current AP settings with wps_er_learn. + - Allow AP filtering based on IP address, add ctrl_iface event for + learned AP settings, add wps_er_config command to configure an AP. + * WPS 2.0: Add support for WPS 2.0 (CONFIG_WPS2) + - Add build option CONFIG_WPS_EXTENSIBILITY_TESTING to enable tool + for testing protocol extensibility. + - Add build option CONFIG_WPS_STRICT to allow disabling of WPS + workarounds. + - Add support for AuthorizedMACs attribute. + * TDLS: + - Propagate TDLS related nl80211 capability flags from kernel and + add them as driver capability flags. If the driver doesn't support + capabilities, assume TDLS is supported internally. When TDLS is + explicitly not supported, disable all user facing TDLS operations. + - Allow TDLS to be disabled at runtime (mostly for testing). + Use set tdls_disabled. + - Honor AP TDLS settings that prohibit/allow TDLS. + - Add a special testing feature for changing TDLS behavior. Use + CONFIG_TDLS_TESTING build param to enable. Configure at runtime + with tdls_testing cli command. + - Add support for TDLS 802.11z. + * wlantest: Add a tool wlantest for IEEE802.11 protocol testing. + wlantest can be used to capture frames from a monitor interface + for realtime capturing or from pcap files for offline analysis. + * Interworking: Support added for 802.11u. Enable in .config with + CONFIG_INTERWORKING. See wpa_supplicant.conf for config parameters + for interworking. wpa_cli commands added to support this are + interworking_select, interworking_connect, anqp_get, fetch_anqp, + and stop_fetch_anqp. + * Android: Add build and runtime support for Android wpa_supplicant. + * bgscan learn: Add new bgscan that learns BSS information based on + previous scans, and uses that information to dynamically generate + the list of channels for background scans. + * Add a new debug message level for excessive information. Use + -ddd to enable. + * TLS: Add support for tls_disable_time_checks=1 in client mode. + * Internal TLS: + - Add support for TLS v1.1 (RFC 4346). Enable with build parameter + CONFIG_TLSV11. + - Add domainComponent parser for X.509 names. + * Linux: Add RFKill support by adding an interface state "disabled". + * Reorder some IEs to get closer to IEEE 802.11 standard. Move + WMM into end of Beacon, Probe Resp and (Re)Assoc Resp frames. + Move HT IEs to be later in (Re)Assoc Resp. + * Solaris: Add support for wired 802.1X client. + * Wi-Fi Direct support. See README-P2P for more information. + * Many bugfixes. + +2010-04-18 - v0.7.2 + * nl80211: fixed number of issues with roaming + * avoid unnecessary roaming if multiple APs with similar signal + strength are present in scan results + * add TLS client events and server probing to ease design of + automatic detection of EAP parameters + * add option for server certificate matching (SHA256 hash of the + certificate) instead of trusted CA certificate configuration + * bsd: Cleaned up driver wrapper and added various low-level + configuration options + * wpa_gui-qt4: do not show too frequent WPS AP available events as + tray messages + * TNC: fixed issues with fragmentation + * EAP-TNC: add Flags field into fragment acknowledgement (needed to + interoperate with other implementations; may potentially breaks + compatibility with older wpa_supplicant/hostapd versions) + * wpa_cli: added option for using a separate process to receive event + messages to reduce latency in showing these + (CFLAGS += -DCONFIG_WPA_CLI_FORK=y in .config to enable this) + * maximum BSS table size can now be configured (bss_max_count) + * BSSes to be included in the BSS table can be filtered based on + configured SSIDs to save memory (filter_ssids) + * fix number of issues with IEEE 802.11r/FT; this version is not + backwards compatible with old versions + * nl80211: add support for IEEE 802.11r/FT protocol (both over-the-air + and over-the-DS) + * add freq_list network configuration parameter to allow the AP + selection to filter out entries based on the operating channel + * add signal strength change events for bgscan; this allows more + dynamic changes to background scanning interval based on changes in + the signal strength with the current AP; this improves roaming within + ESS quite a bit, e.g., with bgscan="simple:30:-45:300" in the network + configuration block to request background scans less frequently when + signal strength remains good and to automatically trigger background + scans whenever signal strength drops noticeably + (this is currently only available with nl80211) + * add BSSID and reason code (if available) to disconnect event messages + * wpa_gui-qt4: more complete support for translating the GUI with + linguist and add German translation + * fix DH padding with internal crypto code (mainly, for WPS) + * do not trigger initial scan automatically anymore if there are no + enabled networks + +2010-01-16 - v0.7.1 + * cleaned up driver wrapper API (struct wpa_driver_ops); the new API + is not fully backwards compatible, so out-of-tree driver wrappers + will need modifications + * cleaned up various module interfaces + * merge hostapd and wpa_supplicant developers' documentation into a + single document + * nl80211: use explicit deauthentication to clear cfg80211 state to + avoid issues when roaming between APs + * dbus: major design changes in the new D-Bus API + (fi.w1.wpa_supplicant1) + * nl80211: added support for IBSS networks + * added internal debugging mechanism with backtrace support and memory + allocation/freeing validation, etc. tests (CONFIG_WPA_TRACE=y) + * added WPS ER unsubscription command to more cleanly unregister from + receiving UPnP events when ER is terminated + * cleaned up AP mode operations to avoid need for virtual driver_ops + wrapper + * added BSS table to maintain more complete scan result information + over multiple scans (that may include only partial results) + * wpa_gui-qt4: update Peers dialog information more dynamically while + the dialog is kept open + * fixed PKCS#12 use with OpenSSL 1.0.0 + * driver_wext: Added cfg80211-specific optimization to avoid some + unnecessary scans and to speed up association + +2009-11-21 - v0.7.0 + * increased wpa_cli ping interval to 5 seconds and made this + configurable with a new command line options (-G) + * fixed scan buffer processing with WEXT to handle up to 65535 + byte result buffer (previously, limited to 32768 bytes) + * allow multiple driver wrappers to be specified on command line + (e.g., -Dnl80211,wext); the first one that is able to initialize the + interface will be used + * added support for multiple SSIDs per scan request to optimize + scan_ssid=1 operations in ap_scan=1 mode (i.e., search for hidden + SSIDs); this requires driver support and can currently be used only + with nl80211 + * added support for WPS USBA out-of-band mechanism with USB Flash + Drives (UFD) (CONFIG_WPS_UFD=y) + * driver_ndis: add PAE group address to the multicast address list to + fix wired IEEE 802.1X authentication + * fixed IEEE 802.11r key derivation function to match with the standard + (note: this breaks interoperability with previous version) [Bug 303] + * added better support for drivers that allow separate authentication + and association commands (e.g., mac80211-based Linux drivers with + nl80211; SME in wpa_supplicant); this allows over-the-air FT protocol + to be used (IEEE 802.11r) + * fixed SHA-256 based key derivation function to match with the + standard when using CCMP (for IEEE 802.11r and IEEE 802.11w) + (note: this breaks interoperability with previous version) [Bug 307] + * use shared driver wrapper files with hostapd + * added AP mode functionality (CONFIG_AP=y) with mode=2 in the network + block; this can be used for open and WPA2-Personal networks + (optionally, with WPS); this links in parts of hostapd functionality + into wpa_supplicant + * wpa_gui-qt4: added new Peers dialog to show information about peers + (other devices, including APs and stations, etc. in the neighborhood) + * added support for WPS External Registrar functionality (configure APs + and enroll new devices); can be used with wpa_gui-qt4 Peers dialog + and wpa_cli commands wps_er_start, wps_er_stop, wps_er_pin, + wps_er_pbc, wps_er_learn + (this can also be used with a new 'none' driver wrapper if no + wireless device or IEEE 802.1X on wired is needed) + * driver_nl80211: multiple updates to provide support for new Linux + nl80211/mac80211 functionality + * updated management frame protection to use IEEE Std 802.11w-2009 + * fixed number of small WPS issues and added workarounds to + interoperate with common deployed broken implementations + * added support for NFC out-of-band mechanism with WPS + * driver_ndis: fixed wired IEEE 802.1X authentication with PAE group + address frames + * added preliminary support for IEEE 802.11r RIC processing + * added support for specifying subset of enabled frequencies to scan + (scan_freq option in the network configuration block); this can speed + up scanning process considerably if it is known that only a small + subset of channels is actually used in the network (this is currently + supported only with -Dnl80211) + * added a workaround for race condition between receiving the + association event and the following EAPOL-Key + * added background scan and roaming infrastructure to allow + network-specific optimizations to be used to improve roaming within + an ESS (same SSID) + * added new DBus interface (fi.w1.wpa_supplicant1) + +2009-01-06 - v0.6.7 + * added support for Wi-Fi Protected Setup (WPS) + (wpa_supplicant can now be configured to act as a WPS Enrollee to + enroll credentials for a network using PIN and PBC methods; in + addition, wpa_supplicant can act as a wireless WPS Registrar to + configure an AP); WPS support can be enabled by adding CONFIG_WPS=y + into .config and setting the runtime configuration variables in + wpa_supplicant.conf (see WPS section in the example configuration + file); new wpa_cli commands wps_pin, wps_pbc, and wps_reg are used to + manage WPS negotiation; see README-WPS for more details + * added support for EAP-AKA' (draft-arkko-eap-aka-kdf) + * added support for using driver_test over UDP socket + * fixed PEAPv0 Cryptobinding interoperability issue with Windows Server + 2008 NPS; optional cryptobinding is now enabled (again) by default + * fixed PSK editing in wpa_gui + * changed EAP-GPSK to use the IANA assigned EAP method type 51 + * added a Windows installer that includes WinPcap and all the needed + DLLs; in addition, it set up the registry automatically so that user + will only need start wpa_gui to get prompted to start the wpasvc + servide and add a new interface if needed through wpa_gui dialog + * updated management frame protection to use IEEE 802.11w/D7.0 + +2008-11-23 - v0.6.6 + * added Milenage SIM/USIM emulator for EAP-SIM/EAP-AKA + (can be used to simulate test SIM/USIM card with a known private key; + enable with CONFIG_SIM_SIMULATOR=y/CONFIG_USIM_SIMULATOR=y in .config + and password="Ki:OPc"/password="Ki:OPc:SQN" in network configuration) + * added a new network configuration option, wpa_ptk_rekey, that can be + used to enforce frequent PTK rekeying, e.g., to mitigate some attacks + against TKIP deficiencies + * added an optional mitigation mechanism for certain attacks against + TKIP by delaying Michael MIC error reports by a random amount of time + between 0 and 60 seconds; this can be enabled with a build option + CONFIG_DELAYED_MIC_ERROR_REPORT=y in .config + * fixed EAP-AKA to use RES Length field in AT_RES as length in bits, + not bytes + * updated OpenSSL code for EAP-FAST to use an updated version of the + session ticket overriding API that was included into the upstream + OpenSSL 0.9.9 tree on 2008-11-15 (no additional OpenSSL patch is + needed with that version anymore) + * updated userspace MLME instructions to match with the current Linux + mac80211 implementation; please also note that this can only be used + with driver_nl80211.c (the old code from driver_wext.c was removed) + * added support (Linux only) for RoboSwitch chipsets (often found in + consumer grade routers); driver interface 'roboswitch' + * fixed canceling of PMKSA caching when using drivers that generate + RSN IE and refuse to drop PMKIDs that wpa_supplicant does not know + about + +2008-11-01 - v0.6.5 + * added support for SHA-256 as X.509 certificate digest when using the + internal X.509/TLSv1 implementation + * updated management frame protection to use IEEE 802.11w/D6.0 + * added support for using SHA256-based stronger key derivation for WPA2 + (IEEE 802.11w) + * fixed FT (IEEE 802.11r) authentication after a failed association to + use correct FTIE + * added support for configuring Phase 2 (inner/tunneled) authentication + method with wpa_gui-qt4 + +2008-08-10 - v0.6.4 + * added support for EAP Sequences in EAP-FAST Phase 2 + * added support for using TNC with EAP-FAST + * added driver_ps3 for the PS3 Linux wireless driver + * added support for optional cryptobinding with PEAPv0 + * fixed the OpenSSL patches (0.9.8g and 0.9.9) for EAP-FAST to + allow fallback to full handshake if server rejects PAC-Opaque + * added fragmentation support for EAP-TNC + * added support for parsing PKCS #8 formatted private keys into the + internal TLS implementation (both PKCS #1 RSA key and PKCS #8 + encapsulated RSA key can now be used) + * added option of using faster, but larger, routines in the internal + LibTomMath (for internal TLS implementation) to speed up DH and RSA + calculations (CONFIG_INTERNAL_LIBTOMMATH_FAST=y) + * fixed race condition between disassociation event and group key + handshake to avoid getting stuck in incorrect state [Bug 261] + * fixed opportunistic key caching (proactive_key_caching) + +2008-02-22 - v0.6.3 + * removed 'nai' and 'eappsk' network configuration variables that were + previously used for configuring user identity and key for EAP-PSK, + EAP-PAX, EAP-SAKE, and EAP-GPSK. 'identity' field is now used as the + replacement for 'nai' (if old configuration used a separate + 'identity' value, that would now be configured as + 'anonymous_identity'). 'password' field is now used as the + replacement for 'eappsk' (it can also be set using hexstring to + present random binary data) + * removed '-w' command line parameter (wait for interface to be added, + if needed); cleaner way of handling this functionality is to use an + external mechanism (e.g., hotplug scripts) that start wpa_supplicant + when an interface is added + * updated FT support to use the latest draft, IEEE 802.11r/D9.0 + * added ctrl_iface monitor event (CTRL-EVENT-SCAN-RESULTS) for + indicating when new scan results become available + * added new ctrl_iface command, BSS, to allow scan results to be + fetched without hitting the message size limits (this command + can be used to iterate through the scan results one BSS at the time) + * fixed EAP-SIM not to include AT_NONCE_MT and AT_SELECTED_VERSION + attributes in EAP-SIM Start/Response when using fast reauthentication + * fixed EAPOL not to end up in infinite loop when processing dynamic + WEP keys with IEEE 802.1X + * fixed problems in getting NDIS events from WMI on Windows 2000 + +2008-01-01 - v0.6.2 + * added support for Makefile builds to include debug-log-to-a-file + functionality (CONFIG_DEBUG_FILE=y and -f on command line) + * fixed EAP-SIM and EAP-AKA message parser to validate attribute + lengths properly to avoid potential crash caused by invalid messages + * added data structure for storing allocated buffers (struct wpabuf); + this does not affect wpa_supplicant usage, but many of the APIs + changed and various interfaces (e.g., EAP) is not compatible with old + versions + * added support for protecting EAP-AKA/Identity messages with + AT_CHECKCODE (optional feature in RFC 4187) + * added support for protected result indication with AT_RESULT_IND for + EAP-SIM and EAP-AKA (phase1="result_ind=1") + * added driver_wext workaround for race condition between scanning and + association with drivers that take very long time to scan all + channels (e.g., madwifi with dual-band cards); wpa_supplicant is now + using a longer hardcoded timeout for the scan if the driver supports + notifications for scan completion (SIOCGIWSCAN event); this helps, + e.g., in cases where wpa_supplicant and madwifi driver ended up in + loop where the driver did not even try to associate + * stop EAPOL timer tick when no timers are in use in order to reduce + power consumption (no need to wake up the process once per second) + [Bug 237] + * added support for privilege separation (run only minimal part of + wpa_supplicant functionality as root and rest as unprivileged, + non-root process); see 'Privilege separation' in README for details; + this is disabled by default and can be enabled with CONFIG_PRIVSEP=y + in .config + * changed scan results data structure to include all information + elements to make it easier to support new IEs; old get_scan_result() + driver_ops is still supported for backwards compatibility (results + are converted internally to the new format), but all drivers should + start using the new get_scan_results2() to make them more likely to + work with new features + * Qt4 version of wpa_gui (wpa_gui-qt4 subdirectory) is now native Qt4 + application, i.e., it does not require Qt3Support anymore; Windows + binary of wpa_gui.exe is now from this directory and only requires + QtCore4.dll and QtGui4.dll libraries + * updated Windows binary build to use Qt 4.3.3 and made Qt DLLs + available as a separate package to make wpa_gui installation easier: + http://w1.fi/wpa_supplicant/qt4/wpa_gui-qt433-windows-dll.zip + * added support for EAP-IKEv2 (draft-tschofenig-eap-ikev2-15.txt); + only shared key/password authentication is supported in this version + +2007-11-24 - v0.6.1 + * added support for configuring password as NtPasswordHash + (16-byte MD4 hash of password) in hash:<32 hex digits> format + * added support for fallback from abbreviated TLS handshake to + full handshake when using EAP-FAST (e.g., due to an expired + PAC-Opaque) + * updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest + draft (draft-ietf-emu-eap-gpsk-07.txt) + * added support for drivers that take care of RSN 4-way handshake + internally (WPA_DRIVER_FLAGS_4WAY_HANDSHAKE in get_capa flags and + WPA_ALG_PMK in set_key) + * added an experimental port for Mac OS X (CONFIG_DRIVER_OSX=y in + .config); this version supports only ap_scan=2 mode and allow the + driver to take care of the 4-way handshake + * fixed a buffer overflow in parsing TSF from scan results when using + driver_wext.c with a driver that includes the TSF (e.g., iwl4965) + [Bug 232] + * updated FT support to use the latest draft, IEEE 802.11r/D8.0 + * fixed an integer overflow issue in the ASN.1 parser used by the + (experimental) internal TLS implementation to avoid a potential + buffer read overflow + * fixed a race condition with -W option (wait for a control interface + monitor before starting) that could have caused the first messages to + be lost + * added support for processing TNCC-TNCS-Messages to report + recommendation (allow/none/isolate) when using TNC [Bug 243] + +2007-05-28 - v0.6.0 + * added network configuration parameter 'frequency' for setting + initial channel for IBSS (adhoc) networks + * added experimental IEEE 802.11r/D6.0 support + * updated EAP-SAKE to RFC 4763 and the IANA-allocated EAP type 48 + * updated EAP-PSK to use the IANA-allocated EAP type 47 + * fixed EAP-PAX key derivation + * fixed EAP-PSK bit ordering of the Flags field + * fixed EAP-PEAP/TTLS/FAST to use the correct EAP identifier in + tunnelled identity request (previously, the identifier from the outer + method was used, not the tunnelled identifier which could be + different) + * added support for fragmentation of outer TLS packets during Phase 2 + of EAP-PEAP/TTLS/FAST + * fixed EAP-TTLS AVP parser processing for too short AVP lengths + * added support for EAP-FAST authentication with inner methods that + generate MSK (e.g., EAP-MSCHAPv2 that was previously only supported + for PAC provisioning) + * added support for authenticated EAP-FAST provisioning + * added support for configuring maximum number of EAP-FAST PACs to + store in a PAC list (fast_max_pac_list_len= in phase1 string) + * added support for storing EAP-FAST PACs in binary format + (fast_pac_format=binary in phase1 string) + * fixed dbus ctrl_iface to validate message interface before + dispatching to avoid a possible segfault [Bug 190] + * fixed PeerKey key derivation to use the correct PRF label + * updated Windows binary build to link against OpenSSL 0.9.8d and + added support for EAP-FAST + * updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest + draft (draft-ietf-emu-eap-gpsk-04.txt) + * fixed EAP-AKA Notification processing to allow Notification to be + processed after AKA Challenge response has been sent + * updated to use IEEE 802.11w/D2.0 for management frame protection + (still experimental) + * fixed EAP-TTLS implementation not to crash on use of freed memory + if TLS library initialization fails + * added support for EAP-TNC (Trusted Network Connect) + (this version implements the EAP-TNC method and EAP-TTLS changes + needed to run two methods in sequence (IF-T) and the IF-IMC and + IF-TNCCS interfaces from TNCC) + +2006-11-24 - v0.5.6 + * added experimental, integrated TLSv1 client implementation with the + needed X.509/ASN.1/RSA/bignum processing (this can be enabled by + setting CONFIG_TLS=internal and CONFIG_INTERNAL_LIBTOMMATH=y in + .config); this can be useful, e.g., if the target system does not + have a suitable TLS library and a minimal code size is required + (total size of this internal TLS/crypto code is bit under 50 kB on + x86 and the crypto code is shared by rest of the supplicant so some + of it was already required; TLSv1/X.509/ASN.1/RSA added about 25 kB) + * removed STAKey handshake since PeerKey handshake has replaced it in + IEEE 802.11ma and there are no known deployments of STAKey + * updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest + draft (draft-ietf-emu-eap-gpsk-01.txt) + * added preliminary implementation of IEEE 802.11w/D1.0 (management + frame protection) + (Note: this requires driver support to work properly.) + (Note2: IEEE 802.11w is an unapproved draft and subject to change.) + * fixed Windows named pipes ctrl_iface to not stop listening for + commands if client program opens a named pipe and closes it + immediately without sending a command + * fixed USIM PIN status determination for the case that PIN is not + needed (this allows EAP-AKA to be used with USIM cards that do not + use PIN) + * added support for reading 3G USIM AID from EF_DIR to allow EAP-AKA to + be used with cards that do not support file selection based on + partial AID + * added support for matching the subjectAltName of the authentication + server certificate against multiple name components (e.g., + altsubject_match="DNS:server.example.com;DNS:server2.example.com") + * fixed EAP-SIM/AKA key derivation for re-authentication case (only + affects IEEE 802.1X with dynamic WEP keys) + * changed ctrl_iface network configuration 'get' operations to not + return password/key material; if these fields are requested, "*" + will be returned if the password/key is set, but the value of the + parameter is not exposed + +2006-08-27 - v0.5.5 + * added support for building Windows version with UNICODE defined + (wide-char functions) + * driver_ndis: fixed static WEP configuration to avoid race condition + issues with some NDIS drivers between association and setting WEP + keys + * driver_ndis: added validation for IELength value in scan results to + avoid crashes when using buggy NDIS drivers [Bug 165] + * fixed Release|Win32 target in the Visual Studio project files + (previously, only Debug|Win32 target was set properly) + * changed control interface API call wpa_ctrl_pending() to allow it to + return -1 on error (e.g., connection lost); control interface clients + will need to make sure that they verify that the value is indeed >0 + when determining whether there are pending messages + * added an alternative control interface backend for Windows targets: + Named Pipe (CONFIG_CTRL_IFACE=named_pipe); this is now the default + control interface mechanism for Windows builds (previously, UDP to + localhost was used) + * changed ctrl_interface configuration for UNIX domain sockets: + - deprecated ctrl_interface_group variable (it may be removed in + future versions) + - allow both directory and group be configured with ctrl_interface + in following format: DIR=/var/run/wpa_supplicant GROUP=wheel + - ctrl_interface=/var/run/wpa_supplicant is still supported for the + case when group is not changed + * added support for controlling more than one interface per process in + Windows version + * added a workaround for a case where the AP is using unknown address + (e.g., MAC address of the wired interface) as the source address for + EAPOL-Key frames; previously, that source address was used as the + destination for EAPOL-Key frames and in key derivation; now, BSSID is + used even if the source address does not match with it + (this resolves an interoperability issue with Thomson SpeedTouch 580) + * added a workaround for UDP-based control interface (which was used in + Windows builds before this release) to prevent packets with forged + addresses from being accepted as local control requests + * removed ndis_events.cpp and possibility of using external + ndis_events.exe; C version (ndis_events.c) is fully functional and + there is no desire to maintain two separate versions of this + implementation + * ndis_events: Changed NDIS event notification design to use WMI to + learn the adapter description through Win32_PnPEntity class; this + should fix some cases where the adapter name was not recognized + correctly (e.g., with some USB WLAN adapters, e.g., Ralink RT2500 + USB) [Bug 113] + * fixed selection of the first network in ap_scan=2 mode; previously, + wpa_supplicant could get stuck in SCANNING state when only the first + network for enabled (e.g., after 'wpa_cli select_network 0') + * winsvc: added support for configuring ctrl_interface parameters in + registry (ctrl_interface string value in + HKLM\SOFTWARE\wpa_supplicant\interfaces\0000 key); this new value is + required to enable control interface (previously, this was hardcoded + to be enabled) + * allow wpa_gui subdirectory to be built with both Qt3 and Qt4 + * converted wpa_gui-qt4 subdirectory to use Qt4 specific project format + +2006-06-20 - v0.5.4 + * fixed build with CONFIG_STAKEY=y [Bug 143] + * added support for doing MLME (IEEE 802.11 management frame + processing) in wpa_supplicant when using Devicescape IEEE 802.11 + stack (wireless-dev.git tree) + * added a new network block configuration option, fragment_size, to + configure the maximum EAP fragment size + * driver_ndis: Disable WZC automatically for the selected interface to + avoid conflicts with two programs trying to control the radio; WZC + will be re-enabled (if it was enabled originally) when wpa_supplicant + is terminated + * added an experimental TLSv1 client implementation + (CONFIG_TLS=internal) that can be used instead of an external TLS + library, e.g., to reduce total size requirement on systems that do + not include any TLS library by default (this is not yet complete; + basic functionality is there, but certificate validation is not yet + included) + * added PeerKey handshake implementation for IEEE 802.11e + direct link setup (DLS) to replace STAKey handshake + * fixed WPA PSK update through ctrl_iface for the case where the old + PSK was derived from an ASCII passphrase and the new PSK is set as + a raw PSK (hex string) + * added new configuration option for identifying which network block + was used (id_str in wpa_supplicant.conf; included on + WPA_EVENT_CONNECT monitor event and as WPA_ID_STR environmental + variable in wpa_cli action scripts; in addition WPA_ID variable is + set to the current unique identifier that wpa_supplicant assigned + automatically for the network and that can be used with + GET_NETWORK/SET_NETWORK ctrl_iface commands) + * wpa_cli action script is now called only when the connect/disconnect + status changes or when associating with a different network + * fixed configuration parser not to remove CCMP from group cipher list + if WPA-None (adhoc) is used (pairwise=NONE in that case) + * fixed integrated NDIS events processing not to hang the process due + to a missed change in eloop_win.c API in v0.5.3 [Bug 155] + * added support for EAP Generalized Pre-Shared Key (EAP-GPSK, + draft-clancy-emu-eap-shared-secret-00.txt) + * added Microsoft Visual Studio 2005 solution and project files for + build wpa_supplicant for Windows (see vs2005 subdirectory) + * eloop_win: fixed unregistration of Windows events + * l2_packet_winpcap: fixed a deadlock in deinitializing l2_packet + at the end of RSN pre-authentication and added unregistration of + a Windows event to avoid getting eloop_win stuck with an invalid + handle + * driver_ndis: added support for selecting AP based on BSSID + * added new environmental variable for wpa_cli action scripts: + WPA_CTRL_DIR is the current control interface directory + * driver_ndis: added support for using NDISUIO instead of WinPcap for + OID set/query operations (CONFIG_USE_NDISUIO=y in .config); with new + l2_packet_ndis (CONFIG_L2_PACKET=ndis), this can be used to build + wpa_supplicant without requiring WinPcap; note that using NDISUIO + requires that WZC is disabled (net stop wzcsvc) since NDISUIO allows + only one application to open the device + * changed NDIS driver naming to only include device GUID, e.g., + {7EE3EFE5-C165-472F-986D-F6FBEDFE8C8D}, instead of including WinPcap + specific \Device\NPF_ prefix before the GUID; the prefix is still + allowed for backwards compatibility, but it is not required anymore + when specifying the interface + * driver_ndis: re-initialize driver interface is the adapter is removed + and re-inserted [Bug 159] + * driver_madwifi: fixed TKIP and CCMP sequence number configuration on + big endian hosts [Bug 146] + +2006-04-27 - v0.5.3 + * fixed EAP-GTC response to include correct user identity when run as + phase 2 method of EAP-FAST (i.e., EAP-FAST did not work in v0.5.2) + * driver_ndis: Fixed encryption mode configuration for unencrypted + networks (some NDIS drivers ignored this, but others, e.g., Broadcom, + refused to associate with open networks) [Bug 106] + * driver_ndis: use BSSID OID polling to detect when IBSS network is + formed even when ndis_events code is included since some NDIS drivers + do not generate media connect events in IBSS mode + * config_winreg: allow global ctrl_interface parameter to be configured + in Windows registry + * config_winreg: added support for saving configuration data into + Windows registry + * added support for controlling network device operational state + (dormant/up) for Linux 2.6.17 to improve DHCP processing (see + http://www.flamewarmaster.de/software/dhcpclient/ for a DHCP client + that can use this information) + * driver_wext: added support for WE-21 change to SSID configuration + * driver_wext: fixed privacy configuration for static WEP keys mode + [Bug 140] + * added an optional driver_ops callback for MLME-SETPROTECTION.request + primitive + * added support for EAP-SAKE (no EAP method number allocated yet, so + this is using the same experimental type 255 as EAP-PSK) + * added support for dynamically loading EAP methods (.so files) instead + of requiring them to be statically linked in; this is disabled by + default (see CONFIG_DYNAMIC_EAP_METHODS in defconfig for information + on how to use this) + +2006-03-19 - v0.5.2 + * do not try to use USIM APDUs when initializing PC/SC for SIM card + access for a network that has not enabled EAP-AKA + * fixed EAP phase 2 Nak for EAP-{PEAP,TTLS,FAST} (this was broken in + v0.5.1 due to the new support for expanded EAP types) + * added support for generating EAP Expanded Nak + * try to fetch scan results once before requesting new scan when + starting up in ap_scan=1 mode (this can speed up initial association + a lot with, e.g., madwifi-ng driver) + * added support for receiving EAPOL frames from a Linux bridge + interface (-bbr0 on command line) + * fixed EAPOL re-authentication for sessions that used PMKSA caching + * changed EAP method registration to use a dynamic list of methods + instead of a static list generated at build time + * fixed PMKSA cache deinitialization not to use freed memory when + removing PMKSA entries + * fixed a memory leak in EAP-TTLS re-authentication + * reject WPA/WPA2 message 3/4 if it does not include any valid + WPA/RSN IE + * driver_wext: added fallback to use SIOCSIWENCODE for setting auth_alg + if the driver does not support SIOCSIWAUTH + +2006-01-29 - v0.5.1 + * driver_test: added better support for multiple APs and STAs by using + a directory with sockets that include MAC address for each device in + the name (driver_param=test_dir=/tmp/test) + * added support for EAP expanded type (vendor specific EAP methods) + * added AP_SCAN command into ctrl_iface so that ap_scan configuration + option can be changed if needed + * wpa_cli/wpa_gui: skip non-socket files in control directory when + using UNIX domain sockets; this avoids selecting an incorrect + interface (e.g., a PID file could be in this directory, even though + use of this directory for something else than socket files is not + recommended) + * fixed TLS library deinitialization after RSN pre-authentication not + to disable TLS library for normal authentication + * driver_wext: Remove null-termination from SSID length if the driver + used it; some Linux drivers do this and they were causing problems in + wpa_supplicant not finding matching configuration block. This change + would break a case where the SSID actually ends in '\0', but that is + not likely to happen in real use. + * fixed PMKSA cache processing not to trigger deauthentication if the + current PMKSA cache entry is replaced with a valid new entry + * fixed PC/SC initialization for ap_scan != 1 modes (this fixes + EAP-SIM and EAP-AKA with real SIM/USIM card when using ap_scan=0 or + ap_scan=2) + +2005-12-18 - v0.5.0 (beginning of 0.5.x development releases) + * added experimental STAKey handshake implementation for IEEE 802.11e + direct link setup (DLS); note: this is disabled by default in both + build and runtime configuration (can be enabled with CONFIG_STAKEY=y + and stakey=1) + * fixed EAP-SIM and EAP-AKA pseudonym and fast re-authentication to + decrypt AT_ENCR_DATA attributes correctly + * fixed EAP-AKA to allow resynchronization within the same session + * made code closer to ANSI C89 standard to make it easier to port to + other C libraries and compilers + * started moving operating system or C library specific functions into + wrapper functions defined in os.h and implemented in os_*.c to make + code more portable + * wpa_supplicant can now be built with Microsoft Visual C++ + (e.g., with the freely available Toolkit 2003 version or Visual + C++ 2005 Express Edition and Platform SDK); see nmake.mak for an + example makefile for nmake + * added support for using Windows registry for command line parameters + (CONFIG_MAIN=main_winsvc) and configuration data + (CONFIG_BACKEND=winreg); see win_example.reg for an example registry + contents; this version can be run both as a Windows service and as a + normal application; 'wpasvc.exe app' to start as applicant, + 'wpasvc.exe reg ' to register a service, + 'net start wpasvc' to start the service, 'wpasvc.exe unreg' to + unregister a service + * made it possible to link ndis_events.exe functionality into + wpa_supplicant.exe by defining CONFIG_NDIS_EVENTS_INTEGRATED + * added better support for multiple control interface backends + (CONFIG_CTRL_IFACE option); currently, 'unix' and 'udp' are supported + * fixed PC/SC code to use correct length for GSM AUTH command buffer + and to not use pioRecvPci with SCardTransmit() calls; these were not + causing visible problems with pcsc-lite, but Windows Winscard.dll + refused the previously used parameters; this fixes EAP-SIM and + EAP-AKA authentication using SIM/USIM card under Windows + * added new event loop implementation for Windows using + WaitForMultipleObject() instead of select() in order to allow waiting + for non-socket objects; this can be selected with + CONFIG_ELOOP=eloop_win in .config + * added support for selecting l2_packet implementation in .config + (CONFIG_L2_PACKET; following options are available now: linux, pcap, + winpcap, freebsd, none) + * added new l2_packet implementation for WinPcap + (CONFIG_L2_PACKET=winpcap) that uses a separate receive thread to + reduce latency in EAPOL receive processing from about 100 ms to about + 3 ms + * added support for EAP-FAST key derivation using other ciphers than + RC4-128-SHA for authentication and AES128-SHA for provisioning + * added support for configuring CA certificate as DER file and as a + configuration blob + * fixed private key configuration as configuration blob and added + support for using PKCS#12 as a blob + * tls_gnutls: added support for using PKCS#12 files; added support for + session resumption + * added support for loading trusted CA certificates from Windows + certificate store: ca_cert="cert_store://", where is + likely CA (Intermediate CA certificates) or ROOT (root certificates) + * added C version of ndis_events.cpp and made it possible to build this + with MinGW so that CONFIG_NDIS_EVENTS_INTEGRATED can be used more + easily on cross-compilation builds + * added wpasvc.exe into Windows binary release; this is an alternative + version of wpa_supplicant.exe with configuration backend using + Windows registry and with the entry point designed to run as a + Windows service + * integrated ndis_events.exe functionality into wpa_supplicant.exe and + wpasvc.exe and removed this additional tool from the Windows binary + release since it is not needed anymore + * load winscard.dll functions dynamically when building with MinGW + since MinGW does not yet include winscard library + +2005-11-20 - v0.4.7 (beginning of 0.4.x stable releases) + * l2_packet_pcap: fixed wired IEEE 802.1X authentication with libpcap + and WinPcap to receive frames sent to PAE group address + * disable EAP state machine when IEEE 802.1X authentication is not used + in order to get rid of bogus "EAP failed" messages + * fixed OpenSSL error reporting to go through all pending errors to + avoid confusing reports of old errors being reported at later point + during handshake + * fixed configuration file updating to not write empty variables + (e.g., proto or key_mgmt) that the file parser would not accept + * fixed ADD_NETWORK ctrl_iface command to use the same default values + for variables as empty network definitions read from config file + would get + * fixed EAP state machine to not discard EAP-Failure messages in many + cases (e.g., during TLS handshake) + * fixed a infinite loop in private key reading if the configured file + cannot be parsed successfully + * driver_madwifi: added support for madwifi-ng + * wpa_gui: do not display password/PSK field contents + * wpa_gui: added CA certificate configuration + * driver_ndis: fixed scan request in ap_scan=2 mode not to change SSID + * driver_ndis: include Beacon IEs in AssocInfo in order to notice if + the new AP is using different WPA/RSN IE + * use longer timeout for IEEE 802.11 association to avoid problems with + drivers that may take more than five second to associate + +2005-10-27 - v0.4.6 + * allow fallback to WPA, if mixed WPA+WPA2 networks have mismatch in + RSN IE, but WPA IE would match with wpa_supplicant configuration + * added support for named configuration blobs in order to avoid having + to use file system for external files (e.g., certificates); + variables can be set to "blob://" instead of file path to + use a named blob; supported fields: pac_file, client_cert, + private_key + * fixed RSN pre-authentication (it was broken in the clean up of WPA + state machine interface in v0.4.5) + * driver_madwifi: set IEEE80211_KEY_GROUP flag for group keys to make + sure the driver configures broadcast decryption correctly + * added ca_path (and ca_path2) configuration variables that can be used + to configure OpenSSL CA path, e.g., /etc/ssl/certs, for using the + system-wide trusted CA list + * added support for starting wpa_supplicant without a configuration + file (-C argument must be used to set ctrl_interface parameter for + this case; in addition, -p argument can be used to provide + driver_param; these new arguments can also be used with a + configuration to override the values from the configuration) + * added global control interface that can be optionally used for adding + and removing network interfaces dynamically (-g command line argument + for both wpa_supplicant and wpa_cli) without having to restart + wpa_supplicant process + * wpa_gui: + - try to save configuration whenever something is modified + - added WEP key configuration + - added possibility to edit the current network configuration + * driver_ndis: fixed driver polling not to increase frequency on each + received EAPOL frame due to incorrectly cancelled timeout + * added simple configuration file examples (in examples subdirectory) + * fixed driver_wext.c to filter wireless events based on ifindex to + avoid interfaces receiving events from other interfaces + * delay sending initial EAPOL-Start couple of seconds to speed up + authentication for the most common case of Authenticator starting + EAP authentication immediately after association + +2005-09-25 - v0.4.5 + * added a workaround for clearing keys with ndiswrapper to allow + roaming from WPA enabled AP to plaintext one + * added docbook documentation (doc/docbook) that can be used to + generate, e.g., man pages + * l2_packet_linux: use socket type SOCK_DGRAM instead of SOCK_RAW for + PF_PACKET in order to prepare for network devices that do not use + Ethernet headers (e.g., network stack that includes IEEE 802.11 + header in the frames) + * use receipt of EAPOL-Key frame as a lower layer success indication + for EAP state machine to allow recovery from dropped EAP-Success + frame + * cleaned up internal EAPOL frame processing by not including link + layer (Ethernet) header during WPA and EAPOL/EAP processing; this + header is added only when transmitted the frame; this makes it easier + to use wpa_supplicant on link layers that use different header than + Ethernet + * updated EAP-PSK to use draft 9 by default since this can now be + tested with hostapd; removed support for draft 3, including + server_nai configuration option from network blocks + * driver_wired: add PAE address to the multicast address list in order + to be able to receive EAPOL frames with drivers that do not include + these multicast addresses by default + * driver_wext: add support for WE-19 + * added support for multiple configuration backends (CONFIG_BACKEND + option); currently, only 'file' is supported (i.e., the format used + in wpa_supplicant.conf) + * added support for updating configuration ('wpa_cli save_config'); + this is disabled by default and can be enabled with global + update_config=1 variable in wpa_supplicant.conf; this allows wpa_cli + and wpa_gui to store the configuration changes in a permanent store + * added GET_NETWORK ctrl_iface command + (e.g., 'wpa_cli get_network 0 ssid') + +2005-08-21 - v0.4.4 + * replaced OpenSSL patch for EAP-FAST support + (openssl-tls-extensions.patch) with a more generic and correct + patch (the new patch is not compatible with the previous one, so the + OpenSSL library will need to be patched with the new patch in order + to be able to build wpa_supplicant with EAP-FAST support) + * added support for using Windows certificate store (through CryptoAPI) + for client certificate and private key operations (EAP-TLS) + (see wpa_supplicant.conf for more information on how to configure + this with private_key) + * ported wpa_gui to Windows + * added Qt4 version of wpa_gui (wpa_gui-qt4 directory); this can be + built with the open source version of the Qt4 for Windows + * allow non-WPA modes (e.g., IEEE 802.1X with dynamic WEP) to be used + with drivers that do not support WPA + * ndis_events: fixed Windows 2000 support + * added support for enabling/disabling networks from the list of all + configured networks ('wpa_cli enable_network ' and + 'wpa_cli disable_network ') + * added support for adding and removing network from the current + configuration ('wpa_cli add_network' and 'wpa_cli remove_network + '); added networks are disabled by default and they can + be enabled with enable_network command once the configuration is done + for the new network; note: configuration file is not yet updated, so + these new networks are lost when wpa_supplicant is restarted + * added support for setting network configuration parameters through + the control interface, for example: + wpa_cli set_network 0 ssid "\"my network\"" + * fixed parsing of strings that include both " and # within double + quoted area (e.g., "start"#end") + * added EAP workaround for PEAP session resumption: allow outer, + i.e., not tunneled, EAP-Success to terminate session since; this can + be disabled with eap_workaround=0 + (this was allowed for PEAPv1 before, but now it is also allowed for + PEAPv0 since at least one RADIUS authentication server seems to be + doing this for PEAPv0, too) + * wpa_gui: added preliminary support for adding new networks to the + wpa_supplicant configuration (double click on the scan results to + open network configuration) + +2005-06-26 - v0.4.3 + * removed interface for external EAPOL/EAP supplicant (e.g., + Xsupplicant), (CONFIG_XSUPPLICANT_IFACE) since it is not required + anymore and is unlikely to be used by anyone + * driver_ndis: fixed WinPcap 3.0 support + * fixed build with CONFIG_DNET_PCAP=y on Linux + * l2_packet: moved different implementations into separate files + (l2_packet_*.c) + +2005-06-12 - v0.4.2 + * driver_ipw: updated driver structures to match with ipw2200-1.0.4 + (note: ipw2100-1.1.0 is likely to require an update to work with + this) + * added support for using ap_scan=2 mode with multiple network blocks; + wpa_supplicant will go through the networks one by one until the + driver reports a successful association; this uses the same order for + networks as scan_ssid=1 scans, i.e., the priority field is ignored + and the network block order in the file is used instead + * fixed a potential issue in RSN pre-authentication ending up using + freed memory if pre-authentication times out + * added support for matching alternative subject name extensions of the + authentication server certificate; new configuration variables + altsubject_match and altsubject_match2 + * driver_ndis: added support for IEEE 802.1X authentication with wired + NDIS drivers + * added support for querying private key password (EAP-TLS) through the + control interface (wpa_cli/wpa_gui) if one is not included in the + configuration file + * driver_broadcom: fixed couple of memory leaks in scan result + processing + * EAP-PAX is now registered as EAP type 46 + * fixed EAP-PAX MAC calculation + * fixed EAP-PAX CK and ICK key derivation + * added support for using password with EAP-PAX (as an alternative to + entering key with eappsk); SHA-1 hash of the password will be used as + the key in this case + * added support for arbitrary driver interface parameters through the + configuration file with a new driver_param field; this adds a new + driver_ops function set_param() + * added possibility to override l2_packet module with driver interface + API (new send_eapol handler); this can be used to implement driver + specific TX/RX functions for EAPOL frames + * fixed ctrl_interface_group processing for the case where gid is + entered as a number, not group name + * driver_test: added support for testing hostapd with wpa_supplicant + by using test driver interface without any kernel drivers or network + cards + +2005-05-22 - v0.4.1 + * driver_madwifi: fixed WPA/WPA2 mode configuration to allow EAPOL + packets to be encrypted; this was apparently broken by the changed + ioctl order in v0.4.0 + * driver_madwifi: added preliminary support for compiling against 'BSD' + branch of madwifi CVS tree + * added support for EAP-MSCHAPv2 password retries within the same EAP + authentication session + * added support for password changes with EAP-MSCHAPv2 (used when the + password has expired) + * added support for reading additional certificates from PKCS#12 files + and adding them to the certificate chain + * fixed association with IEEE 802.1X (no WPA) when dynamic WEP keys + were used + * fixed a possible double free in EAP-TTLS fast-reauthentication when + identity or password is entered through control interface + * display EAP Notification messages to user through control interface + with "CTRL-EVENT-EAP-NOTIFICATION" prefix + * added GUI version of wpa_cli, wpa_gui; this is not build + automatically with 'make'; use 'make wpa_gui' to build (this requires + Qt development tools) + * added 'disconnect' command to control interface for setting + wpa_supplicant in state where it will not associate before + 'reassociate' command has been used + * added support for selecting a network from the list of all configured + networks ('wpa_cli select_network '; this disabled all + other networks; to re-enable, 'wpa_cli select_network any') + * added support for getting scan results through control interface + * added EAP workaround for PEAPv1 session resumption: allow outer, + i.e., not tunneled, EAP-Success to terminate session since; this can + be disabled with eap_workaround=0 + +2005-04-25 - v0.4.0 (beginning of 0.4.x development releases) + * added a new build time option, CONFIG_NO_STDOUT_DEBUG, that can be + used to reduce the size of the wpa_supplicant considerably if + debugging code is not needed + * fixed EAPOL-Key validation to drop packets with invalid Key Data + Length; such frames could have crashed wpa_supplicant due to buffer + overflow + * added support for wired authentication (IEEE 802.1X on wired + Ethernet); driver interface 'wired' + * obsoleted set_wpa() handler in the driver interface API (it can be + replaced by moving enable/disable functionality into init()/deinit()) + (calls to set_wpa() are still present for backwards compatibility, + but they may be removed in the future) + * driver_madwifi: fixed association in plaintext mode + * modified the EAP workaround that accepts EAP-Success with incorrect + Identifier to be even less strict about verification in order to + interoperate with some authentication servers + * added support for sending TLS alerts + * added support for 'any' SSID wildcard; if ssid is not configured or + is set to an empty string, any SSID will be accepted for non-WPA AP + * added support for asking PIN (for SIM) from frontends (e.g., + wpa_cli); if a PIN is needed, but not included in the configuration + file, a control interface request is sent and EAP processing is + delayed until the PIN is available + * added support for using external devices (e.g., a smartcard) for + private key operations in EAP-TLS (CONFIG_SMARTCARD=y in .config); + new wpa_supplicant.conf variables: + - global: opensc_engine_path, pkcs11_engine_path, pkcs11_module_path + - network: engine, engine_id, key_id + * added experimental support for EAP-PAX + * added monitor mode for wpa_cli (-a) that + allows external commands (e.g., shell scripts) to be run based on + wpa_supplicant events, e.g., when authentication has been completed + and data connection is ready; other related wpa_cli arguments: + -B (run in background), -P (write PID file); wpa_supplicant has a new + command line argument (-W) that can be used to make it wait until a + control interface command is received in order to avoid missing + events + * added support for opportunistic WPA2 PMKSA key caching (disabled by + default, can be enabled with proactive_key_caching=1) + * fixed RSN IE in 4-Way Handshake message 2/4 for the case where + Authenticator rejects PMKSA caching attempt and the driver is not + using assoc_info events + * added -P argument for wpa_supplicant to write the current + process id into a file + +2005-02-12 - v0.3.7 (beginning of 0.3.x stable releases) + * added new phase1 option parameter, include_tls_length=1, to force + wpa_supplicant to add TLS Message Length field to all TLS messages + even if the packet is not fragmented; this may be needed with some + authentication servers + * fixed WPA/RSN IE verification in message 3 of 4-Way Handshake when + using drivers that take care of AP selection (e.g., when using + ap_scan=2) + * fixed reprocessing of pending request after ctrl_iface requests for + identity/password/otp + * fixed ctrl_iface requests for identity/password/otp in Phase 2 of + EAP-PEAP and EAP-TTLS + * all drivers using driver_wext: set interface up and select Managed + mode when starting wpa_supplicant; set interface down when exiting + * renamed driver_ipw2100.c to driver_ipw.c since it now supports both + ipw2100 and ipw2200; please note that this also changed the + configuration variable in .config to CONFIG_DRIVER_IPW + +2005-01-24 - v0.3.6 + * fixed a busy loop introduced in v0.3.5 for scan result processing + when no matching AP is found + +2005-01-23 - v0.3.5 + * added a workaround for an interoperability issue with a Cisco AP + when using WPA2-PSK + * fixed non-WPA IEEE 802.1X to use the same authentication timeout as + WPA with IEEE 802.1X (i.e., timeout 10 -> 70 sec to allow + retransmission of dropped frames) + * fixed issues with 64-bit CPUs and SHA1 cleanup in previous version + (e.g., segfault when processing EAPOL-Key frames) + * fixed EAP workaround and fast reauthentication configuration for + RSN pre-authentication; previously these were disabled and + pre-authentication would fail if the used authentication server + requires EAP workarounds + * added support for blacklisting APs that fail or timeout + authentication in ap_scan=1 mode so that all APs are tried in cases + where the ones with strongest signal level are failing authentication + * fixed CA certificate loading after a failed EAP-TLS/PEAP/TTLS + authentication attempt + * allow EAP-PEAP/TTLS fast reauthentication only if Phase 2 succeeded + in the previous authentication (previously, only Phase 1 success was + verified) + +2005-01-09 - v0.3.4 + * added preliminary support for IBSS (ad-hoc) mode configuration + (mode=1 in network block); this included a new key_mgmt mode + WPA-NONE, i.e., TKIP or CCMP with a fixed key (based on psk) and no + key management; see wpa_supplicant.conf for more details and an + example on how to configure this (note: this is currently implemented + only for driver_hostapd.c, but the changes should be trivial to add + in associate() handler for other drivers, too (assuming the driver + supports WPA-None) + * added preliminary port for native Windows (i.e., no cygwin) using + mingw + +2005-01-02 - v0.3.3 + * added optional support for GNU Readline and History Libraries for + wpa_cli (CONFIG_READLINE) + * cleaned up EAP state machine <-> method interface and number of + small problems with error case processing not terminating on + EAP-Failure but waiting for timeout + * added couple of workarounds for interoperability issues with a + Cisco AP when using WPA2 + * added support for EAP-FAST (draft-cam-winget-eap-fast-00.txt); + Note: This requires a patch for openssl to add support for TLS + extensions and number of workarounds for operations without + certificates. Proof of concept type of experimental patch is + included in openssl-tls-extensions.patch. + +2004-12-19 - v0.3.2 + * fixed private key loading for cases where passphrase is not set + * fixed Windows/cygwin L2 packet handler freeing; previous version + could cause a segfault when RSN pre-authentication was completed + * added support for PMKSA caching with drivers that generate RSN IEs + (e.g., NDIS); currently, this is only implemented in driver_ndis.c, + but similar code can be easily added to driver_ndiswrapper.c once + ndiswrapper gets full support for RSN PMKSA caching + * improved recovery from PMKID mismatches by requesting full EAP + authentication in case of failed PMKSA caching attempt + * driver_ndis: added support for NDIS NdisMIncidateStatus() events + (this requires that ndis_events is ran while wpa_supplicant is + running) + * driver_ndis: use ADD_WEP/REMOVE_WEP when configuring WEP keys + * added support for driver interfaces to replace the interface name + based on driver/OS specific mapping, e.g., in case of driver_ndis, + this allows the beginning of the adapter description to be used as + the interface name + * added support for CR+LF (Windows-style) line ends in configuration + file + * driver_ndis: enable radio before starting scanning, disable radio + when exiting + * modified association event handler to set portEnabled = FALSE before + clearing port Valid in order to reset EAP state machine and avoid + problems with new authentication getting ignored because of state + machines ending up in AUTHENTICATED/SUCCESS state based on old + information + * added support for driver events to add PMKID candidates in order to + allow drivers to give priority to most likely roaming candidates + * driver_hostap: moved PrivacyInvoked configuration to associate() + function so that this will not be set for plaintext connections + * added KEY_MGMT_802_1X_NO_WPA as a new key_mgmt type so that driver + interface can distinguish plaintext and IEEE 802.1X (no WPA) + authentication + * fixed static WEP key configuration to use broadcast/default type for + all keys (previously, the default TX key was configured as pairwise/ + unicast key) + * driver_ndis: added legacy WPA capability detection for non-WPA2 + drivers + * added support for setting static WEP keys for IEEE 802.1X without + dynamic WEP keying (eapol_flags=0) + +2004-12-12 - v0.3.1 + * added support for reading PKCS#12 (PFX) files (as a replacement for + PEM/DER) to get certificate and private key (CONFIG_PKCS12) + * fixed compilation with CONFIG_PCSC=y + * added new ap_scan mode, ap_scan=2, for drivers that take care of + association, but need to be configured with security policy and SSID, + e.g., ndiswrapper and NDIS driver; this mode should allow such + drivers to work with hidden SSIDs and optimized roaming; when + ap_scan=2 is used, only the first network block in the configuration + file is used and this configuration should have explicit security + policy (i.e., only one option in the lists) for key_mgmt, pairwise, + group, proto variables + * added experimental port of wpa_supplicant for Windows + - driver_ndis.c driver interface (NDIS OIDs) + - currently, this requires cygwin and WinPcap + - small utility, win_if_list, can be used to get interface name + * control interface can now be removed at build time; add + CONFIG_CTRL_IFACE=y to .config to maintain old functionality + * optional Xsupplicant interface can now be removed at build time; + (CONFIG_XSUPPLICANT_IFACE=y in .config to bring it back) + * added auth_alg to driver interface associate() parameters to make it + easier for drivers to configure authentication algorithm as part of + the association + +2004-12-05 - v0.3.0 (beginning of 0.3.x development releases) + * driver_broadcom: added new driver interface for Broadcom wl.o driver + (a generic driver for Broadcom IEEE 802.11a/g cards) + * wpa_cli: fixed parsing of -p command line argument + * PEAPv1: fixed tunneled EAP-Success reply handling to reply with TLS + ACK, not tunneled EAP-Success (of which only the first byte was + actually send due to a bug in previous code); this seems to + interoperate with most RADIUS servers that implements PEAPv1 + * PEAPv1: added support for terminating PEAP authentication on tunneled + EAP-Success message; this can be configured by adding + peap_outer_success=0 on phase1 parameters in wpa_supplicant.conf + (some RADIUS servers require this whereas others require a tunneled + reply + * PEAPv1: changed phase1 option peaplabel to use default to 0, i.e., to + the old label for key derivation; previously, the default was 1, + but it looks like most existing PEAPv1 implementations use the old + label which is thus more suitable default option + * added support for EAP-PSK (draft-bersani-eap-psk-03.txt) + * fixed parsing of wep_tx_keyidx + * added support for configuring list of allowed Phase 2 EAP types + (for both EAP-PEAP and EAP-TTLS) instead of only one type + * added support for configuring IEEE 802.11 authentication algorithm + (auth_alg; mainly for using Shared Key authentication with static + WEP keys) + * added support for EAP-AKA (with UMTS SIM) + * fixed couple of errors in PCSC handling that could have caused + random-looking errors for EAP-SIM + * added support for EAP-SIM pseudonyms and fast re-authentication + * added support for EAP-TLS/PEAP/TTLS fast re-authentication (TLS + session resumption) + * added support for EAP-SIM with two challenges + (phase1="sim_min_num_chal=3" can be used to require three challenges) + * added support for configuring DH/DSA parameters for an ephemeral DH + key exchange (EAP-TLS/PEAP/TTLS) using new configuration parameters + dh_file and dh_file2 (phase 2); this adds support for using DSA keys + and optional DH key exchange to achieve forward secracy with RSA keys + * added support for matching subject of the authentication server + certificate with a substring when using EAP-TLS/PEAP/TTLS; new + configuration variables subject_match and subject_match2 + * changed SSID configuration in driver_wext.c (used by many driver + interfaces) to use ssid_len+1 as the length for SSID since some Linux + drivers expect this + * fixed couple of unaligned reads in scan result parsing to fix WPA + connection on some platforms (e.g., ARM) + * added driver interface for Intel ipw2100 driver + * added support for LEAP with WPA + * added support for larger scan results report (old limit was 4 kB of + data, i.e., about 35 or so APs) when using Linux wireless extensions + v17 or newer + * fixed a bug in PMKSA cache processing: skip sending of EAPOL-Start + only if there is a PMKSA cache entry for the current AP + * fixed error handling for case where reading of scan results fails: + must schedule a new scan or wpa_supplicant will remain waiting + forever + * changed debug output to remove shared password/key material by + default; all key information can be included with -K command line + argument to match the previous behavior + * added support for timestamping debug log messages (disabled by + default, can be enabled with -t command line argument) + * set pairwise/group cipher suite for non-WPA IEEE 802.1X to WEP-104 + if keys are not configured to be used; this fixes IEEE 802.1X mode + with drivers that use this information to configure whether Privacy + bit can be in Beacon frames (e.g., ndiswrapper) + * avoid clearing driver keys if no keys have been configured since last + key clear request; this seems to improve reliability of group key + handshake for ndiswrapper & NDIS driver which seems to be suffering + of some kind of timing issue when the keys are cleared again after + association + * changed driver interface API: + - WPA_SUPPLICANT_DRIVER_VERSION define can be used to determine which + version is being used (now, this is set to 2; previously, it was + not defined) + - pass pointer to private data structure to all calls + - the new API is not backwards compatible; all in-tree driver + interfaces has been converted to the new API + * added support for controlling multiple interfaces (radios) per + wpa_supplicant process; each interface needs to be listed on the + command line (-c, -i, -D arguments) with -N as a separator + (-cwpa1.conf -iwlan0 -Dhostap -N -cwpa2.conf -iath0 -Dmadwifi) + * added a workaround for EAP servers that incorrectly use same Id for + sequential EAP packets + * changed libpcap/libdnet configuration to use .config variable, + CONFIG_DNET_PCAP, instead of requiring Makefile modification + * improved downgrade attack detection in IE verification of msg 3/4: + verify both WPA and RSN IEs, if present, not only the selected one; + reject the AP if an RSN IE is found in msg 3/4, but not in Beacon or + Probe Response frame, and RSN is enabled in wpa_supplicant + configuration + * fixed WPA msg 3/4 processing to allow Key Data field contain other + IEs than just one WPA IE + * added support for FreeBSD and driver interface for the BSD net80211 + layer (CONFIG_DRIVER_BSD=y in .config); please note that some of the + required kernel mods have not yet been committed + * made EAP workarounds configurable; enabled by default, can be + disabled with network block option eap_workaround=0 + +2004-07-17 - v0.2.4 (beginning of 0.2.x stable releases) + * resolved couple of interoperability issues with EAP-PEAPv1 and + Phase 2 (inner EAP) fragment reassembly + * driver_madwifi: fixed WEP key configuration for IEEE 802.1X when the + AP is using non-zero key index for the unicast key and key index zero + for the broadcast key + * driver_hostap: fixed IEEE 802.1X WEP key updates and + re-authentication by allowing unencrypted EAPOL frames when not using + WPA + * added a new driver interface, 'wext', which uses only standard, + driver independent functionality in Linux wireless extensions; + currently, this can be used only for non-WPA IEEE 802.1X mode, but + eventually, this is to be extended to support full WPA/WPA2 once + Linux wireless extensions get support for this + * added support for mode in which the driver is responsible for AP + scanning and selection; this is disabled by default and can be + enabled with global ap_scan=0 variable in wpa_supplicant.conf; + this mode can be used, e.g., with generic 'wext' driver interface to + use wpa_supplicant as IEEE 802.1X Supplicant with any Linux driver + supporting wireless extensions. + * driver_madwifi: fixed WPA2 configuration and scan_ssid=1 (e.g., + operation with an AP that does not include SSID in the Beacon frames) + * added support for new EAP authentication methods: + EAP-TTLS/EAP-OTP, EAP-PEAPv0/OTP, EAP-PEAPv1/OTP, EAP-OTP + * added support for asking one-time-passwords from frontends (e.g., + wpa_cli); this 'otp' command works otherwise like 'password' command, + but the password is used only once and the frontend will be asked for + a new password whenever a request from authenticator requires a + password; this can be used with both EAP-OTP and EAP-GTC + * changed wpa_cli to automatically re-establish connection so that it + does not need to be re-started when wpa_supplicant is terminated and + started again + * improved user data (identity/password/otp) requests through + frontends: process pending EAPOL packets after getting new + information so that full authentication does not need to be + restarted; in addition, send pending requests again whenever a new + frontend is attached + * changed control frontends to use a new directory for socket files to + make it easier for wpa_cli to automatically select between interfaces + and to provide access control for the control interface; + wpa_supplicant.conf: ctrl_interface is now a path + (/var/run/wpa_supplicant is the recommended path) and + ctrl_interface_group can be used to select which group gets access to + the control interface; + wpa_cli: by default, try to connect to the first interface available + in /var/run/wpa_supplicant; this path can be overridden with -p option + and an interface can be selected with -i option (i.e., in most common + cases, wpa_cli does not need to get any arguments) + * added support for LEAP + * added driver interface for Linux ndiswrapper + * added priority option for network blocks in the configuration file; + this allows networks to be grouped based on priority (the scan + results are searched for matches with network blocks in this order) + +2004-06-20 - v0.2.3 + * sort scan results to improve AP selection + * fixed control interface socket removal for some error cases + * improved scan requesting and authentication timeout + * small improvements/bug fixes for EAP-MSCHAPv2, EAP-PEAP, and + TLS processing + * PEAP version can now be forced with phase1="peapver=" + (mostly for testing; by default, the highest version supported by + both the Supplicant and Authentication Server is selected + automatically) + * added support for madwifi driver (Atheros ar521x) + * added a workaround for cases where AP sets Install Tx/Rx bit for + WPA Group Key messages when pairwise keys are used (without this, + the Group Key would be used for Tx and the AP would drop frames + from the station) + * added GSM SIM/USIM interface for GSM authentication algorithm for + EAP-SIM; this requires pcsc-lite + * added support for ATMEL AT76C5XXx driver + * fixed IEEE 802.1X WEP key derivation in the case where Authenticator + does not include key data in the EAPOL-Key frame (i.e., part of + EAP keying material is used as data encryption key) + * added support for using plaintext and static WEP networks + (key_mgmt=NONE) + +2004-05-31 - v0.2.2 + * added support for new EAP authentication methods: + EAP-TTLS/EAP-MD5-Challenge + EAP-TTLS/EAP-GTC + EAP-TTLS/EAP-MSCHAPv2 + EAP-TTLS/EAP-TLS + EAP-TTLS/MSCHAPv2 + EAP-TTLS/MSCHAP + EAP-TTLS/PAP + EAP-TTLS/CHAP + EAP-PEAP/TLS + EAP-PEAP/GTC + EAP-PEAP/MD5-Challenge + EAP-GTC + EAP-SIM (not yet complete; needs GSM/SIM authentication interface) + * added support for anonymous identity (to be used when identity is + sent in plaintext; real identity will be used within TLS protected + tunnel (e.g., with EAP-TTLS) + * added event messages from wpa_supplicant to frontends, e.g., wpa_cli + * added support for requesting identity and password information using + control interface; in other words, the password for EAP-PEAP or + EAP-TTLS does not need to be included in the configuration file since + a frontand (e.g., wpa_cli) can ask it from the user + * improved RSN pre-authentication to use a candidate list and process + all candidates from each scan; not only one per scan + * fixed RSN IE and WPA IE capabilities field parsing + * ignore Tx bit in GTK IE when Pairwise keys are used + * avoid making new scan requests during IEEE 802.1X negotiation + * use openssl/libcrypto for MD5 and SHA-1 when compiling wpa_supplicant + with TLS support (this replaces the included implementation with + library code to save about 8 kB since the library code is needed + anyway for TLS) + * fixed WPA-PSK only mode when compiled without IEEE 802.1X support + (i.e., without CONFIG_IEEE8021X_EAPOL=y in .config) + +2004-05-06 - v0.2.1 + * added support for internal IEEE 802.1X (actually, IEEE 802.1aa/D6.1) + Supplicant + - EAPOL state machines for Supplicant [IEEE 802.1aa/D6.1] + - EAP peer state machine [draft-ietf-eap-statemachine-02.pdf] + - EAP-MD5 (cannot be used with WPA-RADIUS) + [draft-ietf-eap-rfc2284bis-09.txt] + - EAP-TLS [RFC 2716] + - EAP-MSCHAPv2 (currently used only with EAP-PEAP) + - EAP-PEAP/MSCHAPv2 [draft-josefsson-pppext-eap-tls-eap-07.txt] + [draft-kamath-pppext-eap-mschapv2-00.txt] + (PEAP version 0, 1, and parts of 2; only 0 and 1 are enabled by + default; tested with FreeRADIUS, Microsoft IAS, and Funk Odyssey) + - new configuration file options: eap, identity, password, ca_cert, + client_cert, privatekey, private_key_passwd + - Xsupplicant is not required anymore, but it can be used by + disabling the internal IEEE 802.1X Supplicant with -e command line + option + - this code is not included in the default build; Makefile need to + be edited for this (uncomment lines for selected functionality) + - EAP-TLS and EAP-PEAP require openssl libraries + * use module prefix in debug messages (WPA, EAP, EAP-TLS, ..) + * added support for non-WPA IEEE 802.1X mode with dynamic WEP keys + (i.e., complete IEEE 802.1X/EAP authentication and use IEEE 802.1X + EAPOL-Key frames instead of WPA key handshakes) + * added support for IEEE 802.11i/RSN (WPA2) + - improved PTK Key Handshake + - PMKSA caching, pre-authentication + * fixed wpa_supplicant to ignore possible extra data after WPA + EAPOL-Key packets (this fixes 'Invalid EAPOL-Key MIC when using + TPTK' error from message 3 of 4-Way Handshake in case the AP + includes extra data after the EAPOL-Key) + * added interface for external programs (frontends) to control + wpa_supplicant + - CLI example (wpa_cli) with interactive mode and command line + mode + - replaced SIGUSR1 status/statistics with the new control interface + * made some feature compile time configurable + - .config file for make + - driver interfaces (hostap, hermes, ..) + - EAPOL/EAP functions + +2004-02-15 - v0.2.0 + * Initial version of wpa_supplicant diff --git a/lib/nif/wpa_supplicant/README b/lib/nif/wpa_supplicant/README new file mode 100644 index 0000000..1470c4f --- /dev/null +++ b/lib/nif/wpa_supplicant/README @@ -0,0 +1,56 @@ +wpa_supplicant and hostapd +-------------------------- + +Copyright (c) 2002-2022, Jouni Malinen and contributors +All Rights Reserved. + +These programs are licensed under the BSD license (the one with +advertisement clause removed). + +If you are submitting changes to the project, please see CONTRIBUTIONS +file for more instructions. + + +This package may include either wpa_supplicant, hostapd, or both. See +README file respective subdirectories (wpa_supplicant/README or +hostapd/README) for more details. + +Source code files were moved around in v0.6.x releases and compared to +earlier releases, the programs are now built by first going to a +subdirectory (wpa_supplicant or hostapd) and creating build +configuration (.config) and running 'make' there (for Linux/BSD/cygwin +builds). + + +License +------- + +This software may be distributed, used, and modified under the terms of +BSD license: + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name(s) of the above-listed copyright holder(s) nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/nif/wpa_supplicant/build_config.h b/lib/nif/wpa_supplicant/build_config.h new file mode 100644 index 0000000..c6f4e43 --- /dev/null +++ b/lib/nif/wpa_supplicant/build_config.h @@ -0,0 +1,50 @@ +/* + * wpa_supplicant/hostapd - Build time configuration defines + * Copyright (c) 2005-2006, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + * + * This header file can be used to define configuration defines that were + * originally defined in Makefile. This is mainly meant for IDE use or for + * systems that do not have suitable 'make' tool. In these cases, it may be + * easier to have a single place for defining all the needed C pre-processor + * defines. + */ + +#ifndef BUILD_CONFIG_H +#define BUILD_CONFIG_H + +/* Insert configuration defines, e.g., #define EAP_MD5, here, if needed. */ + +#ifdef CONFIG_WIN32_DEFAULTS +#define CONFIG_NATIVE_WINDOWS +#define CONFIG_ANSI_C_EXTRA +#define CONFIG_WINPCAP +#define IEEE8021X_EAPOL +#define PKCS12_FUNCS +#define PCSC_FUNCS +#define CONFIG_CTRL_IFACE +#define CONFIG_CTRL_IFACE_NAMED_PIPE +#define CONFIG_DRIVER_NDIS +#define CONFIG_NDIS_EVENTS_INTEGRATED +#define CONFIG_DEBUG_FILE +#define EAP_MD5 +#define EAP_TLS +#define EAP_MSCHAPv2 +#define EAP_PEAP +#define EAP_TTLS +#define EAP_GTC +#define EAP_OTP +#define EAP_LEAP +#define EAP_TNC +#define _CRT_SECURE_NO_DEPRECATE + +#ifdef USE_INTERNAL_CRYPTO +#define CONFIG_TLS_INTERNAL_CLIENT +#define CONFIG_INTERNAL_LIBTOMMATH +#define CONFIG_CRYPTO_INTERNAL +#endif /* USE_INTERNAL_CRYPTO */ +#endif /* CONFIG_WIN32_DEFAULTS */ + +#endif /* BUILD_CONFIG_H */ diff --git a/lib/nif/wpa_supplicant/common.h b/lib/nif/wpa_supplicant/common.h new file mode 100644 index 0000000..45f72bb --- /dev/null +++ b/lib/nif/wpa_supplicant/common.h @@ -0,0 +1,598 @@ +/* + * wpa_supplicant/hostapd / common helper functions, etc. + * Copyright (c) 2002-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef COMMON_H +#define COMMON_H + +#include "os.h" + +#if defined(__linux__) || defined(__GLIBC__) +#include +#include +#endif /* __linux__ */ + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ + defined(__OpenBSD__) +#include +#include +#define __BYTE_ORDER _BYTE_ORDER +#define __LITTLE_ENDIAN _LITTLE_ENDIAN +#define __BIG_ENDIAN _BIG_ENDIAN +#ifdef __OpenBSD__ +#define bswap_16 swap16 +#define bswap_32 swap32 +#define bswap_64 swap64 +#else /* __OpenBSD__ */ +#define bswap_16 bswap16 +#define bswap_32 bswap32 +#define bswap_64 bswap64 +#endif /* __OpenBSD__ */ +#endif /* defined(__FreeBSD__) || defined(__NetBSD__) || + * defined(__DragonFly__) || defined(__OpenBSD__) */ + +#ifdef __APPLE__ +#include +#include +#define __BYTE_ORDER _BYTE_ORDER +#define __LITTLE_ENDIAN _LITTLE_ENDIAN +#define __BIG_ENDIAN _BIG_ENDIAN +static inline unsigned short bswap_16(unsigned short v) +{ + return ((v & 0xff) << 8) | (v >> 8); +} + +static inline unsigned int bswap_32(unsigned int v) +{ + return ((v & 0xff) << 24) | ((v & 0xff00) << 8) | + ((v & 0xff0000) >> 8) | (v >> 24); +} +#endif /* __APPLE__ */ + +#ifdef __rtems__ +#include +#define __BYTE_ORDER BYTE_ORDER +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#define __BIG_ENDIAN BIG_ENDIAN +#define bswap_16 CPU_swap_u16 +#define bswap_32 CPU_swap_u32 +#endif /* __rtems__ */ + +#ifdef CONFIG_NATIVE_WINDOWS +#include + +typedef int socklen_t; + +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT 0 /* not supported */ +#endif + +#endif /* CONFIG_NATIVE_WINDOWS */ + +#ifdef _MSC_VER +#define inline __inline + +#undef vsnprintf +#define vsnprintf _vsnprintf +#undef close +#define close closesocket +#endif /* _MSC_VER */ + + +/* Define platform specific integer types */ + +#ifdef _MSC_VER +typedef UINT64 u64; +typedef UINT32 u32; +typedef UINT16 u16; +typedef UINT8 u8; +typedef INT64 s64; +typedef INT32 s32; +typedef INT16 s16; +typedef INT8 s8; +#define WPA_TYPES_DEFINED +#endif /* _MSC_VER */ + +#ifdef __vxworks +typedef unsigned long long u64; +typedef UINT32 u32; +typedef UINT16 u16; +typedef UINT8 u8; +typedef long long s64; +typedef INT32 s32; +typedef INT16 s16; +typedef INT8 s8; +#define WPA_TYPES_DEFINED +#endif /* __vxworks */ + +#ifndef WPA_TYPES_DEFINED +#ifdef CONFIG_USE_INTTYPES_H +#include +#else +#include +#endif +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; +typedef int64_t s64; +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; +#define WPA_TYPES_DEFINED +#endif /* !WPA_TYPES_DEFINED */ + + +/* Define platform specific byte swapping macros */ + +#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS) + +static inline unsigned short wpa_swap_16(unsigned short v) +{ + return ((v & 0xff) << 8) | (v >> 8); +} + +static inline unsigned int wpa_swap_32(unsigned int v) +{ + return ((v & 0xff) << 24) | ((v & 0xff00) << 8) | + ((v & 0xff0000) >> 8) | (v >> 24); +} + +#define le_to_host16(n) (n) +#define host_to_le16(n) (n) +#define be_to_host16(n) wpa_swap_16(n) +#define host_to_be16(n) wpa_swap_16(n) +#define le_to_host32(n) (n) +#define host_to_le32(n) (n) +#define be_to_host32(n) wpa_swap_32(n) +#define host_to_be32(n) wpa_swap_32(n) +#define host_to_le64(n) (n) + +#define WPA_BYTE_SWAP_DEFINED + +#endif /* __CYGWIN__ || CONFIG_NATIVE_WINDOWS */ + + +#ifndef WPA_BYTE_SWAP_DEFINED + +#ifndef __BYTE_ORDER +#ifndef __LITTLE_ENDIAN +#ifndef __BIG_ENDIAN +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#if defined(sparc) +#define __BYTE_ORDER __BIG_ENDIAN +#endif +#endif /* __BIG_ENDIAN */ +#endif /* __LITTLE_ENDIAN */ +#endif /* __BYTE_ORDER */ + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define le_to_host16(n) ((__force u16) (le16) (n)) +#define host_to_le16(n) ((__force le16) (u16) (n)) +#define be_to_host16(n) bswap_16((__force u16) (be16) (n)) +#define host_to_be16(n) ((__force be16) bswap_16((n))) +#define le_to_host32(n) ((__force u32) (le32) (n)) +#define host_to_le32(n) ((__force le32) (u32) (n)) +#define be_to_host32(n) bswap_32((__force u32) (be32) (n)) +#define host_to_be32(n) ((__force be32) bswap_32((n))) +#define le_to_host64(n) ((__force u64) (le64) (n)) +#define host_to_le64(n) ((__force le64) (u64) (n)) +#define be_to_host64(n) bswap_64((__force u64) (be64) (n)) +#define host_to_be64(n) ((__force be64) bswap_64((n))) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define le_to_host16(n) bswap_16(n) +#define host_to_le16(n) bswap_16(n) +#define be_to_host16(n) (n) +#define host_to_be16(n) (n) +#define le_to_host32(n) bswap_32(n) +#define host_to_le32(n) bswap_32(n) +#define be_to_host32(n) (n) +#define host_to_be32(n) (n) +#define le_to_host64(n) bswap_64(n) +#define host_to_le64(n) bswap_64(n) +#define be_to_host64(n) (n) +#define host_to_be64(n) (n) +#ifndef WORDS_BIGENDIAN +#define WORDS_BIGENDIAN +#endif +#else +#error Could not determine CPU byte order +#endif + +#define WPA_BYTE_SWAP_DEFINED +#endif /* !WPA_BYTE_SWAP_DEFINED */ + + +/* Macros for handling unaligned memory accesses */ + +static inline u16 WPA_GET_BE16(const u8 *a) +{ + return (a[0] << 8) | a[1]; +} + +static inline void WPA_PUT_BE16(u8 *a, u16 val) +{ + a[0] = val >> 8; + a[1] = val & 0xff; +} + +static inline u16 WPA_GET_LE16(const u8 *a) +{ + return (a[1] << 8) | a[0]; +} + +static inline void WPA_PUT_LE16(u8 *a, u16 val) +{ + a[1] = val >> 8; + a[0] = val & 0xff; +} + +static inline u32 WPA_GET_BE24(const u8 *a) +{ + return (a[0] << 16) | (a[1] << 8) | a[2]; +} + +static inline void WPA_PUT_BE24(u8 *a, u32 val) +{ + a[0] = (val >> 16) & 0xff; + a[1] = (val >> 8) & 0xff; + a[2] = val & 0xff; +} + +static inline u32 WPA_GET_BE32(const u8 *a) +{ + return ((u32) a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]; +} + +static inline void WPA_PUT_BE32(u8 *a, u32 val) +{ + a[0] = (val >> 24) & 0xff; + a[1] = (val >> 16) & 0xff; + a[2] = (val >> 8) & 0xff; + a[3] = val & 0xff; +} + +static inline u32 WPA_GET_LE32(const u8 *a) +{ + return ((u32) a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]; +} + +static inline void WPA_PUT_LE32(u8 *a, u32 val) +{ + a[3] = (val >> 24) & 0xff; + a[2] = (val >> 16) & 0xff; + a[1] = (val >> 8) & 0xff; + a[0] = val & 0xff; +} + +static inline u64 WPA_GET_BE64(const u8 *a) +{ + return (((u64) a[0]) << 56) | (((u64) a[1]) << 48) | + (((u64) a[2]) << 40) | (((u64) a[3]) << 32) | + (((u64) a[4]) << 24) | (((u64) a[5]) << 16) | + (((u64) a[6]) << 8) | ((u64) a[7]); +} + +static inline void WPA_PUT_BE64(u8 *a, u64 val) +{ + a[0] = val >> 56; + a[1] = val >> 48; + a[2] = val >> 40; + a[3] = val >> 32; + a[4] = val >> 24; + a[5] = val >> 16; + a[6] = val >> 8; + a[7] = val & 0xff; +} + +static inline u64 WPA_GET_LE64(const u8 *a) +{ + return (((u64) a[7]) << 56) | (((u64) a[6]) << 48) | + (((u64) a[5]) << 40) | (((u64) a[4]) << 32) | + (((u64) a[3]) << 24) | (((u64) a[2]) << 16) | + (((u64) a[1]) << 8) | ((u64) a[0]); +} + +static inline void WPA_PUT_LE64(u8 *a, u64 val) +{ + a[7] = val >> 56; + a[6] = val >> 48; + a[5] = val >> 40; + a[4] = val >> 32; + a[3] = val >> 24; + a[2] = val >> 16; + a[1] = val >> 8; + a[0] = val & 0xff; +} + + +#ifndef ETH_ALEN +#define ETH_ALEN 6 +#endif +#ifndef ETH_HLEN +#define ETH_HLEN 14 +#endif +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif +#ifndef ETH_P_ALL +#define ETH_P_ALL 0x0003 +#endif +#ifndef ETH_P_IP +#define ETH_P_IP 0x0800 +#endif +#ifndef ETH_P_80211_ENCAP +#define ETH_P_80211_ENCAP 0x890d /* TDLS comes under this category */ +#endif +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +#endif /* ETH_P_PAE */ +#ifndef ETH_P_EAPOL +#define ETH_P_EAPOL ETH_P_PAE +#endif /* ETH_P_EAPOL */ +#ifndef ETH_P_RSN_PREAUTH +#define ETH_P_RSN_PREAUTH 0x88c7 +#endif /* ETH_P_RSN_PREAUTH */ +#ifndef ETH_P_RRB +#define ETH_P_RRB 0x890D +#endif /* ETH_P_RRB */ +#ifndef ETH_P_OUI +#define ETH_P_OUI 0x88B7 +#endif /* ETH_P_OUI */ +#ifndef ETH_P_8021Q +#define ETH_P_8021Q 0x8100 +#endif /* ETH_P_8021Q */ + + +#ifdef __GNUC__ +#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b)))) +#define STRUCT_PACKED __attribute__ ((packed)) +#else +#define PRINTF_FORMAT(a,b) +#define STRUCT_PACKED +#endif + + +#ifdef CONFIG_ANSI_C_EXTRA + +#if !defined(_MSC_VER) || _MSC_VER < 1400 +/* snprintf - used in number of places; sprintf() is _not_ a good replacement + * due to possible buffer overflow; see, e.g., + * http://www.ijs.si/software/snprintf/ for portable implementation of + * snprintf. */ +int snprintf(char *str, size_t size, const char *format, ...); + +/* vsnprintf - only used for wpa_msg() in wpa_supplicant.c */ +int vsnprintf(char *str, size_t size, const char *format, va_list ap); +#endif /* !defined(_MSC_VER) || _MSC_VER < 1400 */ + +/* getopt - only used in main.c */ +int getopt(int argc, char *const argv[], const char *optstring); +extern char *optarg; +extern int optind; + +#ifndef CONFIG_NO_SOCKLEN_T_TYPEDEF +#ifndef __socklen_t_defined +typedef int socklen_t; +#endif +#endif + +/* inline - define as __inline or just define it to be empty, if needed */ +#ifdef CONFIG_NO_INLINE +#define inline +#else +#define inline __inline +#endif + +#ifndef __func__ +#define __func__ "__func__ not defined" +#endif + +#ifndef bswap_16 +#define bswap_16(a) ((((u16) (a) << 8) & 0xff00) | (((u16) (a) >> 8) & 0xff)) +#endif + +#ifndef bswap_32 +#define bswap_32(a) ((((u32) (a) << 24) & 0xff000000) | \ + (((u32) (a) << 8) & 0xff0000) | \ + (((u32) (a) >> 8) & 0xff00) | \ + (((u32) (a) >> 24) & 0xff)) +#endif + +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT 0 +#endif + +#ifdef _WIN32_WCE +void perror(const char *s); +#endif /* _WIN32_WCE */ + +#endif /* CONFIG_ANSI_C_EXTRA */ + +#ifndef MAC2STR +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" + +/* + * Compact form for string representation of MAC address + * To be used, e.g., for constructing dbus paths for P2P Devices + */ +#define COMPACT_MACSTR "%02x%02x%02x%02x%02x%02x" +#endif + +#ifndef BIT +#define BIT(x) (1U << (x)) +#endif + +/* + * Definitions for sparse validation + * (http://kernel.org/pub/linux/kernel/people/josh/sparse/) + */ +#ifdef __CHECKER__ +#define __force __attribute__((force)) +#undef __bitwise +#define __bitwise __attribute__((bitwise)) +#else +#define __force +#undef __bitwise +#define __bitwise +#endif + +typedef u16 __bitwise be16; +typedef u16 __bitwise le16; +typedef u32 __bitwise be32; +typedef u32 __bitwise le32; +typedef u64 __bitwise be64; +typedef u64 __bitwise le64; + +#ifndef __must_check +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define __must_check __attribute__((__warn_unused_result__)) +#else +#define __must_check +#endif /* __GNUC__ */ +#endif /* __must_check */ + +#ifndef __maybe_unused +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define __maybe_unused __attribute__((unused)) +#else +#define __maybe_unused +#endif /* __GNUC__ */ +#endif /* __must_check */ + +#define SSID_MAX_LEN 32 + +struct wpa_ssid_value { + u8 ssid[SSID_MAX_LEN]; + size_t ssid_len; +}; + +int hwaddr_aton(const char *txt, u8 *addr); +int hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable); +int hwaddr_compact_aton(const char *txt, u8 *addr); +int hwaddr_aton2(const char *txt, u8 *addr); +int hex2byte(const char *hex); +int hexstr2bin(const char *hex, u8 *buf, size_t len); +void inc_byte_array(u8 *counter, size_t len); +void buf_shift_right(u8 *buf, size_t len, size_t bits); +void wpa_get_ntp_timestamp(u8 *buf); +int wpa_scnprintf(char *buf, size_t size, const char *fmt, ...) + PRINTF_FORMAT(3, 4); +int wpa_snprintf_hex_sep(char *buf, size_t buf_size, const u8 *data, size_t len, + char sep); +int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len); +int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data, + size_t len); + +int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask); +int ssid_parse(const char *buf, struct wpa_ssid_value *ssid); + +#ifdef CONFIG_NATIVE_WINDOWS +void wpa_unicode2ascii_inplace(TCHAR *str); +TCHAR * wpa_strdup_tchar(const char *str); +#else /* CONFIG_NATIVE_WINDOWS */ +#define wpa_unicode2ascii_inplace(s) do { } while (0) +#define wpa_strdup_tchar(s) strdup((s)) +#endif /* CONFIG_NATIVE_WINDOWS */ + +void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len); +size_t printf_decode(u8 *buf, size_t maxlen, const char *str); + +const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len); + +char * wpa_config_parse_string(const char *value, size_t *len); +int is_hex(const u8 *data, size_t len); +int has_ctrl_char(const u8 *data, size_t len); +int has_newline(const char *str); +size_t merge_byte_arrays(u8 *res, size_t res_len, + const u8 *src1, size_t src1_len, + const u8 *src2, size_t src2_len); +char * dup_binstr(const void *src, size_t len); + +static inline int is_zero_ether_addr(const u8 *a) +{ + return !(a[0] | a[1] | a[2] | a[3] | a[4] | a[5]); +} + +static inline int is_broadcast_ether_addr(const u8 *a) +{ + return (a[0] & a[1] & a[2] & a[3] & a[4] & a[5]) == 0xff; +} + +static inline int is_multicast_ether_addr(const u8 *a) +{ + return a[0] & 0x01; +} + +#define broadcast_ether_addr (const u8 *) "\xff\xff\xff\xff\xff\xff" + +#include "wpa_debug.h" + + +struct wpa_freq_range_list { + struct wpa_freq_range { + unsigned int min; + unsigned int max; + } *range; + unsigned int num; +}; + +int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value); +int freq_range_list_includes(const struct wpa_freq_range_list *list, + unsigned int freq); +char * freq_range_list_str(const struct wpa_freq_range_list *list); + +size_t int_array_len(const int *a); +void int_array_concat(int **res, const int *a); +void int_array_sort_unique(int *a); +void int_array_add_unique(int **res, int a); + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +void str_clear_free(char *str); +void bin_clear_free(void *bin, size_t len); + +int random_mac_addr(u8 *addr); +int random_mac_addr_keep_oui(u8 *addr); + +const char * cstr_token(const char *str, const char *delim, const char **last); +char * str_token(char *str, const char *delim, char **context); +size_t utf8_escape(const char *inp, size_t in_size, + char *outp, size_t out_size); +size_t utf8_unescape(const char *inp, size_t in_size, + char *outp, size_t out_size); +int is_ctrl_char(char c); + +int str_starts(const char *str, const char *start); + +u8 rssi_to_rcpi(int rssi); +char * get_param(const char *cmd, const char *param); + +void forced_memzero(void *ptr, size_t len); + +/* + * gcc 4.4 ends up generating strict-aliasing warnings about some very common + * networking socket uses that do not really result in a real problem and + * cannot be easily avoided with union-based type-punning due to struct + * definitions including another struct in system header files. To avoid having + * to fully disable strict-aliasing warnings, provide a mechanism to hide the + * typecast from aliasing for now. A cleaner solution will hopefully be found + * in the future to handle these cases. + */ +void * __hide_aliasing_typecast(void *foo); +#define aliasing_hide_typecast(a,t) (t *) __hide_aliasing_typecast((a)) + +#ifdef CONFIG_VALGRIND +#include +#define WPA_MEM_DEFINED(ptr, len) VALGRIND_MAKE_MEM_DEFINED((ptr), (len)) +#else /* CONFIG_VALGRIND */ +#define WPA_MEM_DEFINED(ptr, len) do { } while (0) +#endif /* CONFIG_VALGRIND */ + +#endif /* COMMON_H */ diff --git a/lib/nif/wpa_supplicant/includes.h b/lib/nif/wpa_supplicant/includes.h new file mode 100644 index 0000000..741fc9c --- /dev/null +++ b/lib/nif/wpa_supplicant/includes.h @@ -0,0 +1,46 @@ +/* + * wpa_supplicant/hostapd - Default include files + * Copyright (c) 2005-2006, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + * + * This header file is included into all C files so that commonly used header + * files can be selected with OS specific ifdef blocks in one place instead of + * having to have OS/C library specific selection in many files. + */ + +#ifndef INCLUDES_H +#define INCLUDES_H + +/* Include possible build time configuration before including anything else */ +#include "build_config.h" + +#include +#include +#include +#include +#include +#include +#ifndef _WIN32_WCE +#include +#include +#include +#endif /* _WIN32_WCE */ +#include + +#ifndef _MSC_VER +#include +#endif /* _MSC_VER */ + +#ifndef CONFIG_NATIVE_WINDOWS +#include +#include +#include +#ifndef __vxworks +#include +#include +#endif /* __vxworks */ +#endif /* CONFIG_NATIVE_WINDOWS */ + +#endif /* INCLUDES_H */ diff --git a/lib/nif/wpa_supplicant/os.h b/lib/nif/wpa_supplicant/os.h new file mode 100644 index 0000000..21ba5c3 --- /dev/null +++ b/lib/nif/wpa_supplicant/os.h @@ -0,0 +1,680 @@ +/* + * OS specific functions + * Copyright (c) 2005-2009, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef OS_H +#define OS_H + +typedef long os_time_t; + +/** + * os_sleep - Sleep (sec, usec) + * @sec: Number of seconds to sleep + * @usec: Number of microseconds to sleep + */ +void os_sleep(os_time_t sec, os_time_t usec); + +struct os_time { + os_time_t sec; + os_time_t usec; +}; + +struct os_reltime { + os_time_t sec; + os_time_t usec; +}; + +/** + * os_get_time - Get current time (sec, usec) + * @t: Pointer to buffer for the time + * Returns: 0 on success, -1 on failure + */ +int os_get_time(struct os_time *t); + +/** + * os_get_reltime - Get relative time (sec, usec) + * @t: Pointer to buffer for the time + * Returns: 0 on success, -1 on failure + */ +int os_get_reltime(struct os_reltime *t); + + +/* Helpers for handling struct os_time */ + +static inline int os_time_before(struct os_time *a, struct os_time *b) +{ + return (a->sec < b->sec) || + (a->sec == b->sec && a->usec < b->usec); +} + + +static inline void os_time_sub(struct os_time *a, struct os_time *b, + struct os_time *res) +{ + res->sec = a->sec - b->sec; + res->usec = a->usec - b->usec; + if (res->usec < 0) { + res->sec--; + res->usec += 1000000; + } +} + + +/* Helpers for handling struct os_reltime */ + +static inline int os_reltime_before(struct os_reltime *a, + struct os_reltime *b) +{ + return (a->sec < b->sec) || + (a->sec == b->sec && a->usec < b->usec); +} + + +static inline void os_reltime_sub(struct os_reltime *a, struct os_reltime *b, + struct os_reltime *res) +{ + res->sec = a->sec - b->sec; + res->usec = a->usec - b->usec; + if (res->usec < 0) { + res->sec--; + res->usec += 1000000; + } +} + + +static inline void os_reltime_age(struct os_reltime *start, + struct os_reltime *age) +{ + struct os_reltime now; + + os_get_reltime(&now); + os_reltime_sub(&now, start, age); +} + + +static inline int os_reltime_expired(struct os_reltime *now, + struct os_reltime *ts, + os_time_t timeout_secs) +{ + struct os_reltime age; + + os_reltime_sub(now, ts, &age); + return (age.sec > timeout_secs) || + (age.sec == timeout_secs && age.usec > 0); +} + + +static inline int os_reltime_initialized(struct os_reltime *t) +{ + return t->sec != 0 || t->usec != 0; +} + + +/** + * os_mktime - Convert broken-down time into seconds since 1970-01-01 + * @year: Four digit year + * @month: Month (1 .. 12) + * @day: Day of month (1 .. 31) + * @hour: Hour (0 .. 23) + * @min: Minute (0 .. 59) + * @sec: Second (0 .. 60) + * @t: Buffer for returning calendar time representation (seconds since + * 1970-01-01 00:00:00) + * Returns: 0 on success, -1 on failure + * + * Note: The result is in seconds from Epoch, i.e., in UTC, not in local time + * which is used by POSIX mktime(). + */ +int os_mktime(int year, int month, int day, int hour, int min, int sec, + os_time_t *t); + +struct os_tm { + int sec; /* 0..59 or 60 for leap seconds */ + int min; /* 0..59 */ + int hour; /* 0..23 */ + int day; /* 1..31 */ + int month; /* 1..12 */ + int year; /* Four digit year */ +}; + +int os_gmtime(os_time_t t, struct os_tm *tm); + +/** + * os_daemonize - Run in the background (detach from the controlling terminal) + * @pid_file: File name to write the process ID to or %NULL to skip this + * Returns: 0 on success, -1 on failure + */ +int os_daemonize(const char *pid_file); + +/** + * os_daemonize_terminate - Stop running in the background (remove pid file) + * @pid_file: File name to write the process ID to or %NULL to skip this + */ +void os_daemonize_terminate(const char *pid_file); + +/** + * os_get_random - Get cryptographically strong pseudo random data + * @buf: Buffer for pseudo random data + * @len: Length of the buffer + * Returns: 0 on success, -1 on failure + */ +int os_get_random(unsigned char *buf, size_t len); + +/** + * os_random - Get pseudo random value (not necessarily very strong) + * Returns: Pseudo random value + */ +unsigned long os_random(void); + +/** + * os_rel2abs_path - Get an absolute path for a file + * @rel_path: Relative path to a file + * Returns: Absolute path for the file or %NULL on failure + * + * This function tries to convert a relative path of a file to an absolute path + * in order for the file to be found even if current working directory has + * changed. The returned value is allocated and caller is responsible for + * freeing it. It is acceptable to just return the same path in an allocated + * buffer, e.g., return strdup(rel_path). This function is only used to find + * configuration files when os_daemonize() may have changed the current working + * directory and relative path would be pointing to a different location. + */ +char * os_rel2abs_path(const char *rel_path); + +/** + * os_program_init - Program initialization (called at start) + * Returns: 0 on success, -1 on failure + * + * This function is called when a programs starts. If there are any OS specific + * processing that is needed, it can be placed here. It is also acceptable to + * just return 0 if not special processing is needed. + */ +int os_program_init(void); + +/** + * os_program_deinit - Program deinitialization (called just before exit) + * + * This function is called just before a program exists. If there are any OS + * specific processing, e.g., freeing resourced allocated in os_program_init(), + * it should be done here. It is also acceptable for this function to do + * nothing. + */ +void os_program_deinit(void); + +/** + * os_setenv - Set environment variable + * @name: Name of the variable + * @value: Value to set to the variable + * @overwrite: Whether existing variable should be overwritten + * Returns: 0 on success, -1 on error + * + * This function is only used for wpa_cli action scripts. OS wrapper does not + * need to implement this if such functionality is not needed. + */ +int os_setenv(const char *name, const char *value, int overwrite); + +/** + * os_unsetenv - Delete environent variable + * @name: Name of the variable + * Returns: 0 on success, -1 on error + * + * This function is only used for wpa_cli action scripts. OS wrapper does not + * need to implement this if such functionality is not needed. + */ +int os_unsetenv(const char *name); + +/** + * os_readfile - Read a file to an allocated memory buffer + * @name: Name of the file to read + * @len: For returning the length of the allocated buffer + * Returns: Pointer to the allocated buffer or %NULL on failure + * + * This function allocates memory and reads the given file to this buffer. Both + * binary and text files can be read with this function. The caller is + * responsible for freeing the returned buffer with os_free(). + */ +char * os_readfile(const char *name, size_t *len); + +/** + * os_file_exists - Check whether the specified file exists + * @fname: Path and name of the file + * Returns: 1 if the file exists or 0 if not + */ +int os_file_exists(const char *fname); + +/** + * os_fdatasync - Sync a file's (for a given stream) state with storage device + * @stream: the stream to be flushed + * Returns: 0 if the operation succeeded or -1 on failure + */ +int os_fdatasync(FILE *stream); + +/** + * os_zalloc - Allocate and zero memory + * @size: Number of bytes to allocate + * Returns: Pointer to allocated and zeroed memory or %NULL on failure + * + * Caller is responsible for freeing the returned buffer with os_free(). + */ +void * os_zalloc(size_t size); + +/** + * os_calloc - Allocate and zero memory for an array + * @nmemb: Number of members in the array + * @size: Number of bytes in each member + * Returns: Pointer to allocated and zeroed memory or %NULL on failure + * + * This function can be used as a wrapper for os_zalloc(nmemb * size) when an + * allocation is used for an array. The main benefit over os_zalloc() is in + * having an extra check to catch integer overflows in multiplication. + * + * Caller is responsible for freeing the returned buffer with os_free(). + */ +static inline void * os_calloc(size_t nmemb, size_t size) +{ + if (size && nmemb > (~(size_t) 0) / size) + return NULL; + return os_zalloc(nmemb * size); +} + + +/* + * The following functions are wrapper for standard ANSI C or POSIX functions. + * By default, they are just defined to use the standard function name and no + * os_*.c implementation is needed for them. This avoids extra function calls + * by allowing the C pre-processor take care of the function name mapping. + * + * If the target system uses a C library that does not provide these functions, + * build_config.h can be used to define the wrappers to use a different + * function name. This can be done on function-by-function basis since the + * defines here are only used if build_config.h does not define the os_* name. + * If needed, os_*.c file can be used to implement the functions that are not + * included in the C library on the target system. Alternatively, + * OS_NO_C_LIB_DEFINES can be defined to skip all defines here in which case + * these functions need to be implemented in os_*.c file for the target system. + */ + +#ifdef OS_NO_C_LIB_DEFINES + +/** + * os_malloc - Allocate dynamic memory + * @size: Size of the buffer to allocate + * Returns: Allocated buffer or %NULL on failure + * + * Caller is responsible for freeing the returned buffer with os_free(). + */ +void * os_malloc(size_t size); + +/** + * os_realloc - Re-allocate dynamic memory + * @ptr: Old buffer from os_malloc() or os_realloc() + * @size: Size of the new buffer + * Returns: Allocated buffer or %NULL on failure + * + * Caller is responsible for freeing the returned buffer with os_free(). + * If re-allocation fails, %NULL is returned and the original buffer (ptr) is + * not freed and caller is still responsible for freeing it. + */ +void * os_realloc(void *ptr, size_t size); + +/** + * os_free - Free dynamic memory + * @ptr: Old buffer from os_malloc() or os_realloc(); can be %NULL + */ +void os_free(void *ptr); + +/** + * os_memcpy - Copy memory area + * @dest: Destination + * @src: Source + * @n: Number of bytes to copy + * Returns: dest + * + * The memory areas src and dst must not overlap. os_memmove() can be used with + * overlapping memory. + */ +void * os_memcpy(void *dest, const void *src, size_t n); + +/** + * os_memmove - Copy memory area + * @dest: Destination + * @src: Source + * @n: Number of bytes to copy + * Returns: dest + * + * The memory areas src and dst may overlap. + */ +void * os_memmove(void *dest, const void *src, size_t n); + +/** + * os_memset - Fill memory with a constant byte + * @s: Memory area to be filled + * @c: Constant byte + * @n: Number of bytes started from s to fill with c + * Returns: s + */ +void * os_memset(void *s, int c, size_t n); + +/** + * os_memcmp - Compare memory areas + * @s1: First buffer + * @s2: Second buffer + * @n: Maximum numbers of octets to compare + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greater than s2. Only first n + * characters will be compared. + */ +int os_memcmp(const void *s1, const void *s2, size_t n); + +/** + * os_strdup - Duplicate a string + * @s: Source string + * Returns: Allocated buffer with the string copied into it or %NULL on failure + * + * Caller is responsible for freeing the returned buffer with os_free(). + */ +char * os_strdup(const char *s); + +/** + * os_strlen - Calculate the length of a string + * @s: '\0' terminated string + * Returns: Number of characters in s (not counting the '\0' terminator) + */ +size_t os_strlen(const char *s); + +/** + * os_strcasecmp - Compare two strings ignoring case + * @s1: First string + * @s2: Second string + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greatred than s2 + */ +int os_strcasecmp(const char *s1, const char *s2); + +/** + * os_strncasecmp - Compare two strings ignoring case + * @s1: First string + * @s2: Second string + * @n: Maximum numbers of characters to compare + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greater than s2. Only first n + * characters will be compared. + */ +int os_strncasecmp(const char *s1, const char *s2, size_t n); + +/** + * os_strchr - Locate the first occurrence of a character in string + * @s: String + * @c: Character to search for + * Returns: Pointer to the matched character or %NULL if not found + */ +char * os_strchr(const char *s, int c); + +/** + * os_strrchr - Locate the last occurrence of a character in string + * @s: String + * @c: Character to search for + * Returns: Pointer to the matched character or %NULL if not found + */ +char * os_strrchr(const char *s, int c); + +/** + * os_strcmp - Compare two strings + * @s1: First string + * @s2: Second string + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greatred than s2 + */ +int os_strcmp(const char *s1, const char *s2); + +/** + * os_strncmp - Compare two strings + * @s1: First string + * @s2: Second string + * @n: Maximum numbers of characters to compare + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greater than s2. Only first n + * characters will be compared. + */ +int os_strncmp(const char *s1, const char *s2, size_t n); + +/** + * os_strstr - Locate a substring + * @haystack: String (haystack) to search from + * @needle: Needle to search from haystack + * Returns: Pointer to the beginning of the substring or %NULL if not found + */ +char * os_strstr(const char *haystack, const char *needle); + +/** + * os_snprintf - Print to a memory buffer + * @str: Memory buffer to print into + * @size: Maximum length of the str buffer + * @format: printf format + * Returns: Number of characters printed (not including trailing '\0'). + * + * If the output buffer is truncated, number of characters which would have + * been written is returned. Since some C libraries return -1 in such a case, + * the caller must be prepared on that value, too, to indicate truncation. + * + * Note: Some C library implementations of snprintf() may not guarantee null + * termination in case the output is truncated. The OS wrapper function of + * os_snprintf() should provide this guarantee, i.e., to null terminate the + * output buffer if a C library version of the function is used and if that + * function does not guarantee null termination. + * + * If the target system does not include snprintf(), see, e.g., + * http://www.ijs.si/software/snprintf/ for an example of a portable + * implementation of snprintf. + */ +int os_snprintf(char *str, size_t size, const char *format, ...); + +#else /* OS_NO_C_LIB_DEFINES */ + +#ifdef WPA_TRACE +void * os_malloc(size_t size); +void * os_realloc(void *ptr, size_t size); +void os_free(void *ptr); +char * os_strdup(const char *s); +#else /* WPA_TRACE */ +#ifndef os_malloc +#define os_malloc(s) malloc((s)) +#endif +#ifndef os_realloc +#define os_realloc(p, s) realloc((p), (s)) +#endif +#ifndef os_free +#define os_free(p) free((p)) +#endif +#ifndef os_strdup +#ifdef _MSC_VER +#define os_strdup(s) _strdup(s) +#else +#define os_strdup(s) strdup(s) +#endif +#endif +#endif /* WPA_TRACE */ + +#ifndef os_memcpy +#define os_memcpy(d, s, n) memcpy((d), (s), (n)) +#endif +#ifndef os_memmove +#define os_memmove(d, s, n) memmove((d), (s), (n)) +#endif +#ifndef os_memset +#define os_memset(s, c, n) memset(s, c, n) +#endif +#ifndef os_memcmp +#define os_memcmp(s1, s2, n) memcmp((s1), (s2), (n)) +#endif + +#ifndef os_strlen +#define os_strlen(s) strlen(s) +#endif +#ifndef os_strcasecmp +#ifdef _MSC_VER +#define os_strcasecmp(s1, s2) _stricmp((s1), (s2)) +#else +#define os_strcasecmp(s1, s2) strcasecmp((s1), (s2)) +#endif +#endif +#ifndef os_strncasecmp +#ifdef _MSC_VER +#define os_strncasecmp(s1, s2, n) _strnicmp((s1), (s2), (n)) +#else +#define os_strncasecmp(s1, s2, n) strncasecmp((s1), (s2), (n)) +#endif +#endif +#ifndef os_strchr +#define os_strchr(s, c) strchr((s), (c)) +#endif +#ifndef os_strcmp +#define os_strcmp(s1, s2) strcmp((s1), (s2)) +#endif +#ifndef os_strncmp +#define os_strncmp(s1, s2, n) strncmp((s1), (s2), (n)) +#endif +#ifndef os_strrchr +#define os_strrchr(s, c) strrchr((s), (c)) +#endif +#ifndef os_strstr +#define os_strstr(h, n) strstr((h), (n)) +#endif + +#ifndef os_snprintf +#ifdef _MSC_VER +#define os_snprintf _snprintf +#else +#define os_snprintf snprintf +#endif +#endif + +#endif /* OS_NO_C_LIB_DEFINES */ + + +static inline int os_snprintf_error(size_t size, int res) +{ + return res < 0 || (unsigned int) res >= size; +} + + +static inline void * os_realloc_array(void *ptr, size_t nmemb, size_t size) +{ + if (size && nmemb > (~(size_t) 0) / size) + return NULL; + return os_realloc(ptr, nmemb * size); +} + +/** + * os_remove_in_array - Remove a member from an array by index + * @ptr: Pointer to the array + * @nmemb: Current member count of the array + * @size: The size per member of the array + * @idx: Index of the member to be removed + */ +static inline void os_remove_in_array(void *ptr, size_t nmemb, size_t size, + size_t idx) +{ + if (idx < nmemb - 1) + os_memmove(((unsigned char *) ptr) + idx * size, + ((unsigned char *) ptr) + (idx + 1) * size, + (nmemb - idx - 1) * size); +} + +/** + * os_strlcpy - Copy a string with size bound and NUL-termination + * @dest: Destination + * @src: Source + * @siz: Size of the target buffer + * Returns: Total length of the target string (length of src) (not including + * NUL-termination) + * + * This function matches in behavior with the strlcpy(3) function in OpenBSD. + */ +size_t os_strlcpy(char *dest, const char *src, size_t siz); + +/** + * os_memcmp_const - Constant time memory comparison + * @a: First buffer to compare + * @b: Second buffer to compare + * @len: Number of octets to compare + * Returns: 0 if buffers are equal, non-zero if not + * + * This function is meant for comparing passwords or hash values where + * difference in execution time could provide external observer information + * about the location of the difference in the memory buffers. The return value + * does not behave like os_memcmp(), i.e., os_memcmp_const() cannot be used to + * sort items into a defined order. Unlike os_memcmp(), execution time of + * os_memcmp_const() does not depend on the contents of the compared memory + * buffers, but only on the total compared length. + */ +int os_memcmp_const(const void *a, const void *b, size_t len); + + +/** + * os_memdup - Allocate duplicate of passed memory chunk + * @src: Source buffer to duplicate + * @len: Length of source buffer + * Returns: %NULL if allocation failed, copy of src buffer otherwise + * + * This function allocates a memory block like os_malloc() would, and + * copies the given source buffer into it. + */ +void * os_memdup(const void *src, size_t len); + +/** + * os_exec - Execute an external program + * @program: Path to the program + * @arg: Command line argument string + * @wait_completion: Whether to wait until the program execution completes + * Returns: 0 on success, -1 on error + */ +int os_exec(const char *program, const char *arg, int wait_completion); + + +#ifdef OS_REJECT_C_LIB_FUNCTIONS +#define malloc OS_DO_NOT_USE_malloc +#define realloc OS_DO_NOT_USE_realloc +#define free OS_DO_NOT_USE_free +#define memcpy OS_DO_NOT_USE_memcpy +#define memmove OS_DO_NOT_USE_memmove +#define memset OS_DO_NOT_USE_memset +#define memcmp OS_DO_NOT_USE_memcmp +#undef strdup +#define strdup OS_DO_NOT_USE_strdup +#define strlen OS_DO_NOT_USE_strlen +#define strcasecmp OS_DO_NOT_USE_strcasecmp +#define strncasecmp OS_DO_NOT_USE_strncasecmp +#undef strchr +#define strchr OS_DO_NOT_USE_strchr +#undef strcmp +#define strcmp OS_DO_NOT_USE_strcmp +#undef strncmp +#define strncmp OS_DO_NOT_USE_strncmp +#undef strncpy +#define strncpy OS_DO_NOT_USE_strncpy +#define strrchr OS_DO_NOT_USE_strrchr +#define strstr OS_DO_NOT_USE_strstr +#undef snprintf +#define snprintf OS_DO_NOT_USE_snprintf + +#define strcpy OS_DO_NOT_USE_strcpy +#endif /* OS_REJECT_C_LIB_FUNCTIONS */ + + +#if defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS) +#define TEST_FAIL() testing_test_fail() +int testing_test_fail(void); +extern char wpa_trace_fail_func[256]; +extern unsigned int wpa_trace_fail_after; +extern char wpa_trace_test_fail_func[256]; +extern unsigned int wpa_trace_test_fail_after; +#else +#define TEST_FAIL() 0 +#endif + +#endif /* OS_H */ diff --git a/lib/nif/wpa_supplicant/os_unix.c b/lib/nif/wpa_supplicant/os_unix.c new file mode 100644 index 0000000..258deef --- /dev/null +++ b/lib/nif/wpa_supplicant/os_unix.c @@ -0,0 +1,853 @@ +/* + * OS specific functions for UNIX/POSIX systems + * Copyright (c) 2005-2019, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "includes.h" + +#include +#include + +#ifdef ANDROID +#include +#include +#include +#endif /* ANDROID */ + +#ifdef __MACH__ +#include +#include +#include +#endif /* __MACH__ */ + +#include "os.h" +#include "common.h" + +#ifdef WPA_TRACE + +#include "wpa_debug.h" +#include "trace.h" +#include "list.h" + +static struct dl_list alloc_list = DL_LIST_HEAD_INIT(alloc_list); + +#define ALLOC_MAGIC 0xa84ef1b2 +#define FREED_MAGIC 0x67fd487a + +struct os_alloc_trace { + unsigned int magic; + struct dl_list list __attribute__((aligned(16))); + size_t len; + WPA_TRACE_INFO +} __attribute__((aligned(16))); + +#endif /* WPA_TRACE */ + + +void os_sleep(os_time_t sec, os_time_t usec) +{ +#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L) + const struct timespec req = { sec, usec * 1000 }; + + nanosleep(&req, NULL); +#else + if (sec) + sleep(sec); + if (usec) + usleep(usec); +#endif +} + + +int os_get_time(struct os_time *t) +{ + int res; + struct timeval tv; + res = gettimeofday(&tv, NULL); + t->sec = tv.tv_sec; + t->usec = tv.tv_usec; + return res; +} + + +int os_get_reltime(struct os_reltime *t) +{ +#ifndef __MACH__ +#if defined(CLOCK_BOOTTIME) + static clockid_t clock_id = CLOCK_BOOTTIME; +#elif defined(CLOCK_MONOTONIC) + static clockid_t clock_id = CLOCK_MONOTONIC; +#else + static clockid_t clock_id = CLOCK_REALTIME; +#endif + struct timespec ts; + int res; + + if (TEST_FAIL()) + return -1; + + while (1) { + res = clock_gettime(clock_id, &ts); + if (res == 0) { + t->sec = ts.tv_sec; + t->usec = ts.tv_nsec / 1000; + return 0; + } + switch (clock_id) { +#ifdef CLOCK_BOOTTIME + case CLOCK_BOOTTIME: + clock_id = CLOCK_MONOTONIC; + break; +#endif +#ifdef CLOCK_MONOTONIC + case CLOCK_MONOTONIC: + clock_id = CLOCK_REALTIME; + break; +#endif + case CLOCK_REALTIME: + return -1; + } + } +#else /* __MACH__ */ + uint64_t abstime, nano; + static mach_timebase_info_data_t info = { 0, 0 }; + + if (!info.denom) { + if (mach_timebase_info(&info) != KERN_SUCCESS) + return -1; + } + + abstime = mach_absolute_time(); + nano = (abstime * info.numer) / info.denom; + + t->sec = nano / NSEC_PER_SEC; + t->usec = (nano - (((uint64_t) t->sec) * NSEC_PER_SEC)) / NSEC_PER_USEC; + + return 0; +#endif /* __MACH__ */ +} + + +int os_mktime(int year, int month, int day, int hour, int min, int sec, + os_time_t *t) +{ + struct tm tm, *tm1; + time_t t_local, t1, t2; + os_time_t tz_offset; + + if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 || + hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 || + sec > 60) + return -1; + + memset(&tm, 0, sizeof(tm)); + tm.tm_year = year - 1900; + tm.tm_mon = month - 1; + tm.tm_mday = day; + tm.tm_hour = hour; + tm.tm_min = min; + tm.tm_sec = sec; + + t_local = mktime(&tm); + + /* figure out offset to UTC */ + tm1 = localtime(&t_local); + if (tm1) { + t1 = mktime(tm1); + tm1 = gmtime(&t_local); + if (tm1) { + t2 = mktime(tm1); + tz_offset = t2 - t1; + } else + tz_offset = 0; + } else + tz_offset = 0; + + *t = (os_time_t) t_local - tz_offset; + return 0; +} + + +int os_gmtime(os_time_t t, struct os_tm *tm) +{ + struct tm *tm2; + time_t t2 = t; + + tm2 = gmtime(&t2); + if (tm2 == NULL) + return -1; + tm->sec = tm2->tm_sec; + tm->min = tm2->tm_min; + tm->hour = tm2->tm_hour; + tm->day = tm2->tm_mday; + tm->month = tm2->tm_mon + 1; + tm->year = tm2->tm_year + 1900; + return 0; +} + + +#ifdef __APPLE__ +#include +static int os_daemon(int nochdir, int noclose) +{ + int devnull; + + if (chdir("/") < 0) + return -1; + + devnull = open("/dev/null", O_RDWR); + if (devnull < 0) + return -1; + + if (dup2(devnull, STDIN_FILENO) < 0) { + close(devnull); + return -1; + } + + if (dup2(devnull, STDOUT_FILENO) < 0) { + close(devnull); + return -1; + } + + if (dup2(devnull, STDERR_FILENO) < 0) { + close(devnull); + return -1; + } + + return 0; +} +#else /* __APPLE__ */ +#define os_daemon daemon +#endif /* __APPLE__ */ + + +int os_daemonize(const char *pid_file) +{ +#if defined(__uClinux__) || defined(__sun__) + return -1; +#else /* defined(__uClinux__) || defined(__sun__) */ + if (os_daemon(0, 0)) { + perror("daemon"); + return -1; + } + + if (pid_file) { + FILE *f = fopen(pid_file, "w"); + if (f) { + fprintf(f, "%u\n", getpid()); + fclose(f); + } + } + + return -0; +#endif /* defined(__uClinux__) || defined(__sun__) */ +} + + +void os_daemonize_terminate(const char *pid_file) +{ + if (pid_file) + unlink(pid_file); +} + + +int os_get_random(unsigned char *buf, size_t len) +{ +#ifdef TEST_FUZZ + size_t i; + + for (i = 0; i < len; i++) + buf[i] = i & 0xff; + return 0; +#else /* TEST_FUZZ */ + FILE *f; + size_t rc; + + if (TEST_FAIL()) + return -1; + + f = fopen("/dev/urandom", "rb"); + if (f == NULL) { + printf("Could not open /dev/urandom.\n"); + return -1; + } + + rc = fread(buf, 1, len, f); + fclose(f); + + return rc != len ? -1 : 0; +#endif /* TEST_FUZZ */ +} + + +unsigned long os_random(void) +{ + return random(); +} + + +char * os_rel2abs_path(const char *rel_path) +{ + char *buf = NULL, *cwd, *ret; + size_t len = 128, cwd_len, rel_len, ret_len; + int last_errno; + + if (!rel_path) + return NULL; + + if (rel_path[0] == '/') + return os_strdup(rel_path); + + for (;;) { + buf = os_malloc(len); + if (buf == NULL) + return NULL; + cwd = getcwd(buf, len); + if (cwd == NULL) { + last_errno = errno; + os_free(buf); + if (last_errno != ERANGE) + return NULL; + len *= 2; + if (len > 2000) + return NULL; + } else { + buf[len - 1] = '\0'; + break; + } + } + + cwd_len = os_strlen(cwd); + rel_len = os_strlen(rel_path); + ret_len = cwd_len + 1 + rel_len + 1; + ret = os_malloc(ret_len); + if (ret) { + os_memcpy(ret, cwd, cwd_len); + ret[cwd_len] = '/'; + os_memcpy(ret + cwd_len + 1, rel_path, rel_len); + ret[ret_len - 1] = '\0'; + } + os_free(buf); + return ret; +} + + +int os_program_init(void) +{ + unsigned int seed; + +#ifdef ANDROID + /* + * We ignore errors here since errors are normal if we + * are already running as non-root. + */ +#ifdef ANDROID_SETGROUPS_OVERRIDE + gid_t groups[] = { ANDROID_SETGROUPS_OVERRIDE }; +#else /* ANDROID_SETGROUPS_OVERRIDE */ + gid_t groups[] = { AID_INET, AID_WIFI, AID_KEYSTORE }; +#endif /* ANDROID_SETGROUPS_OVERRIDE */ + struct __user_cap_header_struct header; + struct __user_cap_data_struct cap; + + setgroups(ARRAY_SIZE(groups), groups); + + prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); + + setgid(AID_WIFI); + setuid(AID_WIFI); + + header.version = _LINUX_CAPABILITY_VERSION; + header.pid = 0; + cap.effective = cap.permitted = + (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW); + cap.inheritable = 0; + capset(&header, &cap); +#endif /* ANDROID */ + + if (os_get_random((unsigned char *) &seed, sizeof(seed)) == 0) + srandom(seed); + + return 0; +} + + +void os_program_deinit(void) +{ +#ifdef WPA_TRACE + struct os_alloc_trace *a; + unsigned long total = 0; + dl_list_for_each(a, &alloc_list, struct os_alloc_trace, list) { + total += a->len; + if (a->magic != ALLOC_MAGIC) { + wpa_printf(MSG_INFO, "MEMLEAK[%p]: invalid magic 0x%x " + "len %lu", + a, a->magic, (unsigned long) a->len); + continue; + } + wpa_printf(MSG_INFO, "MEMLEAK[%p]: len %lu", + a, (unsigned long) a->len); + wpa_trace_dump("memleak", a); + } + if (total) + wpa_printf(MSG_INFO, "MEMLEAK: total %lu bytes", + (unsigned long) total); + wpa_trace_deinit(); +#endif /* WPA_TRACE */ +} + + +int os_setenv(const char *name, const char *value, int overwrite) +{ + return setenv(name, value, overwrite); +} + + +int os_unsetenv(const char *name) +{ +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || \ + defined(__OpenBSD__) + unsetenv(name); + return 0; +#else + return unsetenv(name); +#endif +} + + +char * os_readfile(const char *name, size_t *len) +{ + FILE *f; + char *buf; + long pos; + + f = fopen(name, "rb"); + if (f == NULL) + return NULL; + + if (fseek(f, 0, SEEK_END) < 0 || (pos = ftell(f)) < 0) { + fclose(f); + return NULL; + } + *len = pos; + if (fseek(f, 0, SEEK_SET) < 0) { + fclose(f); + return NULL; + } + + buf = os_malloc(*len); + if (buf == NULL) { + fclose(f); + return NULL; + } + + if (fread(buf, 1, *len, f) != *len) { + fclose(f); + os_free(buf); + return NULL; + } + + fclose(f); + + return buf; +} + + +int os_file_exists(const char *fname) +{ + return access(fname, F_OK) == 0; +} + + +int os_fdatasync(FILE *stream) +{ + if (!fflush(stream)) { +#if defined __FreeBSD__ || defined __linux__ + return fdatasync(fileno(stream)); +#else /* !__linux__ && !__FreeBSD__ */ +#ifdef F_FULLFSYNC + /* OS X does not implement fdatasync(). */ + return fcntl(fileno(stream), F_FULLFSYNC); +#else /* F_FULLFSYNC */ + return fsync(fileno(stream)); +#endif /* F_FULLFSYNC */ +#endif /* __linux__ */ + } + + return -1; +} + + +#ifndef WPA_TRACE +void * os_zalloc(size_t size) +{ + return calloc(1, size); +} +#endif /* WPA_TRACE */ + + +size_t os_strlcpy(char *dest, const char *src, size_t siz) +{ + const char *s = src; + size_t left = siz; + + if (left) { + /* Copy string up to the maximum size of the dest buffer */ + while (--left != 0) { + if ((*dest++ = *s++) == '\0') + break; + } + } + + if (left == 0) { + /* Not enough room for the string; force NUL-termination */ + if (siz != 0) + *dest = '\0'; + while (*s++) + ; /* determine total src string length */ + } + + return s - src - 1; +} + + +int os_memcmp_const(const void *a, const void *b, size_t len) +{ + const u8 *aa = a; + const u8 *bb = b; + size_t i; + u8 res; + + for (res = 0, i = 0; i < len; i++) + res |= aa[i] ^ bb[i]; + + return res; +} + + +void * os_memdup(const void *src, size_t len) +{ + void *r = os_malloc(len); + + if (r && src) + os_memcpy(r, src, len); + return r; +} + + +#ifdef WPA_TRACE + +#if defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS) +char wpa_trace_fail_func[256] = { 0 }; +unsigned int wpa_trace_fail_after; + +static int testing_fail_alloc(void) +{ + const char *func[WPA_TRACE_LEN]; + size_t i, res, len; + char *pos, *next; + int match; + + if (!wpa_trace_fail_after) + return 0; + + res = wpa_trace_calling_func(func, WPA_TRACE_LEN); + i = 0; + if (i < res && os_strcmp(func[i], __func__) == 0) + i++; + if (i < res && os_strcmp(func[i], "os_malloc") == 0) + i++; + if (i < res && os_strcmp(func[i], "os_zalloc") == 0) + i++; + if (i < res && os_strcmp(func[i], "os_calloc") == 0) + i++; + if (i < res && os_strcmp(func[i], "os_realloc") == 0) + i++; + if (i < res && os_strcmp(func[i], "os_realloc_array") == 0) + i++; + if (i < res && os_strcmp(func[i], "os_strdup") == 0) + i++; + if (i < res && os_strcmp(func[i], "os_memdup") == 0) + i++; + + pos = wpa_trace_fail_func; + + match = 0; + while (i < res) { + int allow_skip = 1; + int maybe = 0; + + if (*pos == '=') { + allow_skip = 0; + pos++; + } else if (*pos == '?') { + maybe = 1; + pos++; + } + next = os_strchr(pos, ';'); + if (next) + len = next - pos; + else + len = os_strlen(pos); + if (os_memcmp(pos, func[i], len) != 0) { + if (maybe && next) { + pos = next + 1; + continue; + } + if (allow_skip) { + i++; + continue; + } + return 0; + } + if (!next) { + match = 1; + break; + } + pos = next + 1; + i++; + } + if (!match) + return 0; + + wpa_trace_fail_after--; + if (wpa_trace_fail_after == 0) { + wpa_printf(MSG_INFO, "TESTING: fail allocation at %s", + wpa_trace_fail_func); + for (i = 0; i < res; i++) + wpa_printf(MSG_INFO, "backtrace[%d] = %s", + (int) i, func[i]); + return 1; + } + + return 0; +} + + +char wpa_trace_test_fail_func[256] = { 0 }; +unsigned int wpa_trace_test_fail_after; + +int testing_test_fail(void) +{ + const char *func[WPA_TRACE_LEN]; + size_t i, res, len; + char *pos, *next; + int match; + + if (!wpa_trace_test_fail_after) + return 0; + + res = wpa_trace_calling_func(func, WPA_TRACE_LEN); + i = 0; + if (i < res && os_strcmp(func[i], __func__) == 0) + i++; + + pos = wpa_trace_test_fail_func; + + match = 0; + while (i < res) { + int allow_skip = 1; + int maybe = 0; + + if (*pos == '=') { + allow_skip = 0; + pos++; + } else if (*pos == '?') { + maybe = 1; + pos++; + } + next = os_strchr(pos, ';'); + if (next) + len = next - pos; + else + len = os_strlen(pos); + if (os_memcmp(pos, func[i], len) != 0) { + if (maybe && next) { + pos = next + 1; + continue; + } + if (allow_skip) { + i++; + continue; + } + return 0; + } + if (!next) { + match = 1; + break; + } + pos = next + 1; + i++; + } + if (!match) + return 0; + + wpa_trace_test_fail_after--; + if (wpa_trace_test_fail_after == 0) { + wpa_printf(MSG_INFO, "TESTING: fail at %s", + wpa_trace_test_fail_func); + for (i = 0; i < res; i++) + wpa_printf(MSG_INFO, "backtrace[%d] = %s", + (int) i, func[i]); + return 1; + } + + return 0; +} + +#else + +static inline int testing_fail_alloc(void) +{ + return 0; +} +#endif + +void * os_malloc(size_t size) +{ + struct os_alloc_trace *a; + + if (testing_fail_alloc()) + return NULL; + + a = malloc(sizeof(*a) + size); + if (a == NULL) + return NULL; + a->magic = ALLOC_MAGIC; + dl_list_add(&alloc_list, &a->list); + a->len = size; + wpa_trace_record(a); + return a + 1; +} + + +void * os_realloc(void *ptr, size_t size) +{ + struct os_alloc_trace *a; + size_t copy_len; + void *n; + + if (ptr == NULL) + return os_malloc(size); + + a = (struct os_alloc_trace *) ptr - 1; + if (a->magic != ALLOC_MAGIC) { + wpa_printf(MSG_INFO, "REALLOC[%p]: invalid magic 0x%x%s", + a, a->magic, + a->magic == FREED_MAGIC ? " (already freed)" : ""); + wpa_trace_show("Invalid os_realloc() call"); + abort(); + } + n = os_malloc(size); + if (n == NULL) + return NULL; + copy_len = a->len; + if (copy_len > size) + copy_len = size; + os_memcpy(n, a + 1, copy_len); + os_free(ptr); + return n; +} + + +void os_free(void *ptr) +{ + struct os_alloc_trace *a; + + if (ptr == NULL) + return; + a = (struct os_alloc_trace *) ptr - 1; + if (a->magic != ALLOC_MAGIC) { + wpa_printf(MSG_INFO, "FREE[%p]: invalid magic 0x%x%s", + a, a->magic, + a->magic == FREED_MAGIC ? " (already freed)" : ""); + wpa_trace_show("Invalid os_free() call"); + abort(); + } + dl_list_del(&a->list); + a->magic = FREED_MAGIC; + + wpa_trace_check_ref(ptr); + free(a); +} + + +void * os_zalloc(size_t size) +{ + void *ptr = os_malloc(size); + if (ptr) + os_memset(ptr, 0, size); + return ptr; +} + + +char * os_strdup(const char *s) +{ + size_t len; + char *d; + len = os_strlen(s); + d = os_malloc(len + 1); + if (d == NULL) + return NULL; + os_memcpy(d, s, len); + d[len] = '\0'; + return d; +} + +#endif /* WPA_TRACE */ + + +int os_exec(const char *program, const char *arg, int wait_completion) +{ + pid_t pid; + int pid_status; + + pid = fork(); + if (pid < 0) { + perror("fork"); + return -1; + } + + if (pid == 0) { + /* run the external command in the child process */ + const int MAX_ARG = 30; + char *_program, *_arg, *pos; + char *argv[MAX_ARG + 1]; + int i; + + _program = os_strdup(program); + _arg = os_strdup(arg); + + argv[0] = _program; + + i = 1; + pos = _arg; + while (i < MAX_ARG && pos && *pos) { + while (*pos == ' ') + pos++; + if (*pos == '\0') + break; + argv[i++] = pos; + pos = os_strchr(pos, ' '); + if (pos) + *pos++ = '\0'; + } + argv[i] = NULL; + + execv(program, argv); + perror("execv"); + os_free(_program); + os_free(_arg); + exit(0); + return -1; + } + + if (wait_completion) { + /* wait for the child process to complete in the parent */ + waitpid(pid, &pid_status, 0); + } + + return 0; +} diff --git a/lib/nif/wpa_supplicant/wpa_ctrl.c b/lib/nif/wpa_supplicant/wpa_ctrl.c new file mode 100644 index 0000000..40a9795 --- /dev/null +++ b/lib/nif/wpa_supplicant/wpa_ctrl.c @@ -0,0 +1,766 @@ +/* + * wpa_supplicant/hostapd control interface library + * Copyright (c) 2004-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "includes.h" + +#ifdef CONFIG_CTRL_IFACE + +#ifdef CONFIG_CTRL_IFACE_UNIX +#include +#include +#include +#include +#include +#endif /* CONFIG_CTRL_IFACE_UNIX */ +#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE +#include +#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ + +#ifdef ANDROID +#include +#include +#include +#include "private/android_filesystem_config.h" +#endif /* ANDROID */ + +#ifdef CONFIG_CTRL_IFACE_UDP_IPV6 +#include +#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + +#include "wpa_ctrl.h" +#include "common.h" + + +#if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP) +#define CTRL_IFACE_SOCKET +#endif /* CONFIG_CTRL_IFACE_UNIX || CONFIG_CTRL_IFACE_UDP */ + + +/** + * struct wpa_ctrl - Internal structure for control interface library + * + * This structure is used by the wpa_supplicant/hostapd control interface + * library to store internal data. Programs using the library should not touch + * this data directly. They can only use the pointer to the data structure as + * an identifier for the control interface connection and use this as one of + * the arguments for most of the control interface library functions. + */ +struct wpa_ctrl { +#ifdef CONFIG_CTRL_IFACE_UDP + int s; +#ifdef CONFIG_CTRL_IFACE_UDP_IPV6 + struct sockaddr_in6 local; + struct sockaddr_in6 dest; +#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + struct sockaddr_in local; + struct sockaddr_in dest; +#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + char *cookie; + char *remote_ifname; + char *remote_ip; +#endif /* CONFIG_CTRL_IFACE_UDP */ +#ifdef CONFIG_CTRL_IFACE_UNIX + int s; + struct sockaddr_un local; + struct sockaddr_un dest; +#endif /* CONFIG_CTRL_IFACE_UNIX */ +#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE + HANDLE pipe; +#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ +}; + + +#ifdef CONFIG_CTRL_IFACE_UNIX + +#ifndef CONFIG_CTRL_IFACE_CLIENT_DIR +#define CONFIG_CTRL_IFACE_CLIENT_DIR "/tmp" +#endif /* CONFIG_CTRL_IFACE_CLIENT_DIR */ +#ifndef CONFIG_CTRL_IFACE_CLIENT_PREFIX +#define CONFIG_CTRL_IFACE_CLIENT_PREFIX "wpa_ctrl_" +#endif /* CONFIG_CTRL_IFACE_CLIENT_PREFIX */ + + +struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path) +{ + return wpa_ctrl_open2(ctrl_path, NULL); +} + + +struct wpa_ctrl * wpa_ctrl_open2(const char *ctrl_path, + const char *cli_path) +{ + struct wpa_ctrl *ctrl; + static int counter = 0; + int ret; + size_t res; + int tries = 0; + int flags; + + if (ctrl_path == NULL) + return NULL; + + ctrl = os_zalloc(sizeof(*ctrl)); + if (ctrl == NULL) + return NULL; + + ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0); + if (ctrl->s < 0) { + os_free(ctrl); + return NULL; + } + + ctrl->local.sun_family = AF_UNIX; + counter++; +try_again: + if (cli_path && cli_path[0] == '/') { + ret = os_snprintf(ctrl->local.sun_path, + sizeof(ctrl->local.sun_path), + "%s/" CONFIG_CTRL_IFACE_CLIENT_PREFIX "%d-%d", + cli_path, (int) getpid(), counter); + } else { + ret = os_snprintf(ctrl->local.sun_path, + sizeof(ctrl->local.sun_path), + CONFIG_CTRL_IFACE_CLIENT_DIR "/" + CONFIG_CTRL_IFACE_CLIENT_PREFIX "%d-%d", + (int) getpid(), counter); + } + if (os_snprintf_error(sizeof(ctrl->local.sun_path), ret)) { + close(ctrl->s); + os_free(ctrl); + return NULL; + } + tries++; +#ifdef ANDROID + /* Set client socket file permissions so that bind() creates the client + * socket with these permissions and there is no need to try to change + * them with chmod() after bind() which would have potential issues with + * race conditions. These permissions are needed to make sure the server + * side (wpa_supplicant or hostapd) can reply to the control interface + * messages. + * + * The lchown() calls below after bind() are also part of the needed + * operations to allow the response to go through. Those are using the + * no-deference-symlinks version to avoid races. */ + fchmod(ctrl->s, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); +#endif /* ANDROID */ + if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, + sizeof(ctrl->local)) < 0) { + if (errno == EADDRINUSE && tries < 2) { + /* + * getpid() returns unique identifier for this instance + * of wpa_ctrl, so the existing socket file must have + * been left by unclean termination of an earlier run. + * Remove the file and try again. + */ + unlink(ctrl->local.sun_path); + goto try_again; + } + close(ctrl->s); + os_free(ctrl); + return NULL; + } + +#ifdef ANDROID + /* Set group even if we do not have privileges to change owner */ + lchown(ctrl->local.sun_path, -1, AID_WIFI); + lchown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI); + + if (os_strncmp(ctrl_path, "@android:", 9) == 0) { + if (socket_local_client_connect( + ctrl->s, ctrl_path + 9, + ANDROID_SOCKET_NAMESPACE_RESERVED, + SOCK_DGRAM) < 0) { + close(ctrl->s); + unlink(ctrl->local.sun_path); + os_free(ctrl); + return NULL; + } + return ctrl; + } + + /* + * If the ctrl_path isn't an absolute pathname, assume that + * it's the name of a socket in the Android reserved namespace. + * Otherwise, it's a normal UNIX domain socket appearing in the + * filesystem. + */ + if (*ctrl_path != '/') { + char buf[21]; + os_snprintf(buf, sizeof(buf), "wpa_%s", ctrl_path); + if (socket_local_client_connect( + ctrl->s, buf, + ANDROID_SOCKET_NAMESPACE_RESERVED, + SOCK_DGRAM) < 0) { + close(ctrl->s); + unlink(ctrl->local.sun_path); + os_free(ctrl); + return NULL; + } + return ctrl; + } +#endif /* ANDROID */ + + ctrl->dest.sun_family = AF_UNIX; + if (os_strncmp(ctrl_path, "@abstract:", 10) == 0) { + ctrl->dest.sun_path[0] = '\0'; + os_strlcpy(ctrl->dest.sun_path + 1, ctrl_path + 10, + sizeof(ctrl->dest.sun_path) - 1); + } else { + res = os_strlcpy(ctrl->dest.sun_path, ctrl_path, + sizeof(ctrl->dest.sun_path)); + if (res >= sizeof(ctrl->dest.sun_path)) { + close(ctrl->s); + os_free(ctrl); + return NULL; + } + } + if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest, + sizeof(ctrl->dest)) < 0) { + close(ctrl->s); + unlink(ctrl->local.sun_path); + os_free(ctrl); + return NULL; + } + + /* + * Make socket non-blocking so that we don't hang forever if + * target dies unexpectedly. + */ + flags = fcntl(ctrl->s, F_GETFL); + if (flags >= 0) { + flags |= O_NONBLOCK; + if (fcntl(ctrl->s, F_SETFL, flags) < 0) { + perror("fcntl(ctrl->s, O_NONBLOCK)"); + /* Not fatal, continue on.*/ + } + } + + return ctrl; +} + + +void wpa_ctrl_close(struct wpa_ctrl *ctrl) +{ + if (ctrl == NULL) + return; + unlink(ctrl->local.sun_path); + if (ctrl->s >= 0) + close(ctrl->s); + os_free(ctrl); +} + + +#ifdef ANDROID +/** + * wpa_ctrl_cleanup() - Delete any local UNIX domain socket files that + * may be left over from clients that were previously connected to + * wpa_supplicant. This keeps these files from being orphaned in the + * event of crashes that prevented them from being removed as part + * of the normal orderly shutdown. + */ +void wpa_ctrl_cleanup(void) +{ + DIR *dir; + struct dirent *result; + size_t dirnamelen; + size_t maxcopy; + char pathname[PATH_MAX]; + char *namep; + + if ((dir = opendir(CONFIG_CTRL_IFACE_CLIENT_DIR)) == NULL) + return; + + dirnamelen = (size_t) os_snprintf(pathname, sizeof(pathname), "%s/", + CONFIG_CTRL_IFACE_CLIENT_DIR); + if (dirnamelen >= sizeof(pathname)) { + closedir(dir); + return; + } + namep = pathname + dirnamelen; + maxcopy = PATH_MAX - dirnamelen; + while ((result = readdir(dir)) != NULL) { + if (os_strlcpy(namep, result->d_name, maxcopy) < maxcopy) + unlink(pathname); + } + closedir(dir); +} +#endif /* ANDROID */ + +#else /* CONFIG_CTRL_IFACE_UNIX */ + +#ifdef ANDROID +void wpa_ctrl_cleanup(void) +{ +} +#endif /* ANDROID */ + +#endif /* CONFIG_CTRL_IFACE_UNIX */ + + +#ifdef CONFIG_CTRL_IFACE_UDP + +struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path) +{ + struct wpa_ctrl *ctrl; + char buf[128]; + size_t len; +#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE + struct hostent *h; +#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ + + ctrl = os_zalloc(sizeof(*ctrl)); + if (ctrl == NULL) + return NULL; + +#ifdef CONFIG_CTRL_IFACE_UDP_IPV6 + ctrl->s = socket(PF_INET6, SOCK_DGRAM, 0); +#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + ctrl->s = socket(PF_INET, SOCK_DGRAM, 0); +#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + if (ctrl->s < 0) { + perror("socket"); + os_free(ctrl); + return NULL; + } + +#ifdef CONFIG_CTRL_IFACE_UDP_IPV6 + ctrl->local.sin6_family = AF_INET6; +#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE + ctrl->local.sin6_addr = in6addr_any; +#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */ + inet_pton(AF_INET6, "::1", &ctrl->local.sin6_addr); +#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ +#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + ctrl->local.sin_family = AF_INET; +#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE + ctrl->local.sin_addr.s_addr = INADDR_ANY; +#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */ + ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1); +#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ +#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + + if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, + sizeof(ctrl->local)) < 0) { + close(ctrl->s); + os_free(ctrl); + return NULL; + } + +#ifdef CONFIG_CTRL_IFACE_UDP_IPV6 + ctrl->dest.sin6_family = AF_INET6; + inet_pton(AF_INET6, "::1", &ctrl->dest.sin6_addr); + ctrl->dest.sin6_port = htons(WPA_CTRL_IFACE_PORT); +#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + ctrl->dest.sin_family = AF_INET; + ctrl->dest.sin_addr.s_addr = htonl((127 << 24) | 1); + ctrl->dest.sin_port = htons(WPA_CTRL_IFACE_PORT); +#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + +#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE + if (ctrl_path) { + char *port, *name; + int port_id; +#ifdef CONFIG_CTRL_IFACE_UDP_IPV6 + char *scope; + int scope_id = 0; +#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + + name = os_strdup(ctrl_path); + if (name == NULL) { + close(ctrl->s); + os_free(ctrl); + return NULL; + } +#ifdef CONFIG_CTRL_IFACE_UDP_IPV6 + port = os_strchr(name, ','); +#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + port = os_strchr(name, ':'); +#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + + if (port) { + port_id = atoi(&port[1]); + port[0] = '\0'; + } else + port_id = WPA_CTRL_IFACE_PORT; + +#ifdef CONFIG_CTRL_IFACE_UDP_IPV6 + scope = os_strchr(name, '%'); + if (scope) { + scope_id = if_nametoindex(&scope[1]); + scope[0] = '\0'; + } + h = gethostbyname2(name, AF_INET6); +#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + h = gethostbyname(name); +#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + ctrl->remote_ip = os_strdup(name); + os_free(name); + if (h == NULL) { + perror("gethostbyname"); + close(ctrl->s); + os_free(ctrl->remote_ip); + os_free(ctrl); + return NULL; + } +#ifdef CONFIG_CTRL_IFACE_UDP_IPV6 + ctrl->dest.sin6_scope_id = scope_id; + ctrl->dest.sin6_port = htons(port_id); + os_memcpy(&ctrl->dest.sin6_addr, h->h_addr, h->h_length); +#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + ctrl->dest.sin_port = htons(port_id); + os_memcpy(&ctrl->dest.sin_addr.s_addr, h->h_addr, h->h_length); +#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + } else + ctrl->remote_ip = os_strdup("localhost"); +#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */ + + if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest, + sizeof(ctrl->dest)) < 0) { +#ifdef CONFIG_CTRL_IFACE_UDP_IPV6 + char addr[INET6_ADDRSTRLEN]; + wpa_printf(MSG_ERROR, "connect(%s:%d) failed: %s", + inet_ntop(AF_INET6, &ctrl->dest.sin6_addr, addr, + sizeof(ctrl->dest)), + ntohs(ctrl->dest.sin6_port), + strerror(errno)); +#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + wpa_printf(MSG_ERROR, "connect(%s:%d) failed: %s", + inet_ntoa(ctrl->dest.sin_addr), + ntohs(ctrl->dest.sin_port), + strerror(errno)); +#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */ + close(ctrl->s); + os_free(ctrl->remote_ip); + os_free(ctrl); + return NULL; + } + + len = sizeof(buf) - 1; + if (wpa_ctrl_request(ctrl, "GET_COOKIE", 10, buf, &len, NULL) == 0) { + buf[len] = '\0'; + ctrl->cookie = os_strdup(buf); + } + + if (wpa_ctrl_request(ctrl, "IFNAME", 6, buf, &len, NULL) == 0) { + buf[len] = '\0'; + ctrl->remote_ifname = os_strdup(buf); + } + + return ctrl; +} + + +char * wpa_ctrl_get_remote_ifname(struct wpa_ctrl *ctrl) +{ +#define WPA_CTRL_MAX_PS_NAME 100 + static char ps[WPA_CTRL_MAX_PS_NAME] = {}; + os_snprintf(ps, WPA_CTRL_MAX_PS_NAME, "%s/%s", + ctrl->remote_ip, ctrl->remote_ifname); + return ps; +} + + +void wpa_ctrl_close(struct wpa_ctrl *ctrl) +{ + close(ctrl->s); + os_free(ctrl->cookie); + os_free(ctrl->remote_ifname); + os_free(ctrl->remote_ip); + os_free(ctrl); +} + +#endif /* CONFIG_CTRL_IFACE_UDP */ + + +#ifdef CTRL_IFACE_SOCKET +int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len, + char *reply, size_t *reply_len, + void (*msg_cb)(char *msg, size_t len)) +{ + struct timeval tv; + struct os_reltime started_at; + int res; + fd_set rfds; + const char *_cmd; + char *cmd_buf = NULL; + size_t _cmd_len; + +#ifdef CONFIG_CTRL_IFACE_UDP + if (ctrl->cookie) { + char *pos; + _cmd_len = os_strlen(ctrl->cookie) + 1 + cmd_len; + cmd_buf = os_malloc(_cmd_len); + if (cmd_buf == NULL) + return -1; + _cmd = cmd_buf; + pos = cmd_buf; + os_strlcpy(pos, ctrl->cookie, _cmd_len); + pos += os_strlen(ctrl->cookie); + *pos++ = ' '; + os_memcpy(pos, cmd, cmd_len); + } else +#endif /* CONFIG_CTRL_IFACE_UDP */ + { + _cmd = cmd; + _cmd_len = cmd_len; + } + + errno = 0; + started_at.sec = 0; + started_at.usec = 0; +retry_send: + if (send(ctrl->s, _cmd, _cmd_len, 0) < 0) { + if (errno == EAGAIN || errno == EBUSY || errno == EWOULDBLOCK) + { + /* + * Must be a non-blocking socket... Try for a bit + * longer before giving up. + */ + if (started_at.sec == 0) + os_get_reltime(&started_at); + else { + struct os_reltime n; + os_get_reltime(&n); + /* Try for a few seconds. */ + if (os_reltime_expired(&n, &started_at, 5)) + goto send_err; + } + os_sleep(1, 0); + goto retry_send; + } + send_err: + os_free(cmd_buf); + return -1; + } + os_free(cmd_buf); + + for (;;) { + tv.tv_sec = 10; + tv.tv_usec = 0; + FD_ZERO(&rfds); + FD_SET(ctrl->s, &rfds); + res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv); + if (res < 0 && errno == EINTR) + continue; + if (res < 0) + return res; + if (FD_ISSET(ctrl->s, &rfds)) { + res = recv(ctrl->s, reply, *reply_len, 0); + if (res < 0) + return res; + if ((res > 0 && reply[0] == '<') || + (res > 6 && strncmp(reply, "IFNAME=", 7) == 0)) { + /* This is an unsolicited message from + * wpa_supplicant, not the reply to the + * request. Use msg_cb to report this to the + * caller. */ + if (msg_cb) { + /* Make sure the message is nul + * terminated. */ + if ((size_t) res == *reply_len) + res = (*reply_len) - 1; + reply[res] = '\0'; + msg_cb(reply, res); + } + continue; + } + *reply_len = res; + break; + } else { + return -2; + } + } + return 0; +} +#endif /* CTRL_IFACE_SOCKET */ + + +static int wpa_ctrl_attach_helper(struct wpa_ctrl *ctrl, int attach) +{ + char buf[10]; + int ret; + size_t len = 10; + + ret = wpa_ctrl_request(ctrl, attach ? "ATTACH" : "DETACH", 6, + buf, &len, NULL); + if (ret < 0) + return ret; + if (len == 3 && os_memcmp(buf, "OK\n", 3) == 0) + return 0; + return -1; +} + + +int wpa_ctrl_attach(struct wpa_ctrl *ctrl) +{ + return wpa_ctrl_attach_helper(ctrl, 1); +} + + +int wpa_ctrl_detach(struct wpa_ctrl *ctrl) +{ + return wpa_ctrl_attach_helper(ctrl, 0); +} + + +#ifdef CTRL_IFACE_SOCKET + +int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len) +{ + int res; + + res = recv(ctrl->s, reply, *reply_len, 0); + if (res < 0) + return res; + *reply_len = res; + return 0; +} + + +int wpa_ctrl_pending(struct wpa_ctrl *ctrl) +{ + struct timeval tv; + fd_set rfds; + tv.tv_sec = 0; + tv.tv_usec = 0; + FD_ZERO(&rfds); + FD_SET(ctrl->s, &rfds); + select(ctrl->s + 1, &rfds, NULL, NULL, &tv); + return FD_ISSET(ctrl->s, &rfds); +} + + +int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl) +{ + return ctrl->s; +} + +#endif /* CTRL_IFACE_SOCKET */ + + +#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE + +#ifndef WPA_SUPPLICANT_NAMED_PIPE +#define WPA_SUPPLICANT_NAMED_PIPE "WpaSupplicant" +#endif +#define NAMED_PIPE_PREFIX TEXT("\\\\.\\pipe\\") TEXT(WPA_SUPPLICANT_NAMED_PIPE) + +struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path) +{ + struct wpa_ctrl *ctrl; + DWORD mode; + TCHAR name[256]; + int i, ret; + + ctrl = os_malloc(sizeof(*ctrl)); + if (ctrl == NULL) + return NULL; + os_memset(ctrl, 0, sizeof(*ctrl)); + +#ifdef UNICODE + if (ctrl_path == NULL) + ret = _snwprintf(name, 256, NAMED_PIPE_PREFIX); + else + ret = _snwprintf(name, 256, NAMED_PIPE_PREFIX TEXT("-%S"), + ctrl_path); +#else /* UNICODE */ + if (ctrl_path == NULL) + ret = os_snprintf(name, 256, NAMED_PIPE_PREFIX); + else + ret = os_snprintf(name, 256, NAMED_PIPE_PREFIX "-%s", + ctrl_path); +#endif /* UNICODE */ + if (os_snprintf_error(256, ret)) { + os_free(ctrl); + return NULL; + } + + for (i = 0; i < 10; i++) { + ctrl->pipe = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, + NULL, OPEN_EXISTING, 0, NULL); + /* + * Current named pipe server side in wpa_supplicant is + * re-opening the pipe for new clients only after the previous + * one is taken into use. This leaves a small window for race + * conditions when two connections are being opened at almost + * the same time. Retry if that was the case. + */ + if (ctrl->pipe != INVALID_HANDLE_VALUE || + GetLastError() != ERROR_PIPE_BUSY) + break; + WaitNamedPipe(name, 1000); + } + if (ctrl->pipe == INVALID_HANDLE_VALUE) { + os_free(ctrl); + return NULL; + } + + mode = PIPE_READMODE_MESSAGE; + if (!SetNamedPipeHandleState(ctrl->pipe, &mode, NULL, NULL)) { + CloseHandle(ctrl->pipe); + os_free(ctrl); + return NULL; + } + + return ctrl; +} + + +void wpa_ctrl_close(struct wpa_ctrl *ctrl) +{ + CloseHandle(ctrl->pipe); + os_free(ctrl); +} + + +int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len, + char *reply, size_t *reply_len, + void (*msg_cb)(char *msg, size_t len)) +{ + DWORD written; + DWORD readlen = *reply_len; + + if (!WriteFile(ctrl->pipe, cmd, cmd_len, &written, NULL)) + return -1; + + if (!ReadFile(ctrl->pipe, reply, *reply_len, &readlen, NULL)) + return -1; + *reply_len = readlen; + + return 0; +} + + +int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len) +{ + DWORD len = *reply_len; + if (!ReadFile(ctrl->pipe, reply, *reply_len, &len, NULL)) + return -1; + *reply_len = len; + return 0; +} + + +int wpa_ctrl_pending(struct wpa_ctrl *ctrl) +{ + DWORD left; + + if (!PeekNamedPipe(ctrl->pipe, NULL, 0, NULL, &left, NULL)) + return -1; + return left ? 1 : 0; +} + + +int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl) +{ + return -1; +} + +#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ + +#endif /* CONFIG_CTRL_IFACE */ diff --git a/lib/nif/wpa_supplicant/wpa_ctrl.h b/lib/nif/wpa_supplicant/wpa_ctrl.h new file mode 100644 index 0000000..137b07c --- /dev/null +++ b/lib/nif/wpa_supplicant/wpa_ctrl.h @@ -0,0 +1,643 @@ +/* + * wpa_supplicant/hostapd control interface library + * Copyright (c) 2004-2017, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef WPA_CTRL_H +#define WPA_CTRL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* wpa_supplicant control interface - fixed message prefixes */ + +/** Interactive request for identity/password/pin */ +#define WPA_CTRL_REQ "CTRL-REQ-" + +/** Response to identity/password/pin request */ +#define WPA_CTRL_RSP "CTRL-RSP-" + +/* Event messages with fixed prefix */ +/** Authentication completed successfully and data connection enabled */ +#define WPA_EVENT_CONNECTED "CTRL-EVENT-CONNECTED " +/** Disconnected, data connection is not available */ +#define WPA_EVENT_DISCONNECTED "CTRL-EVENT-DISCONNECTED " +/** Association rejected during connection attempt */ +#define WPA_EVENT_ASSOC_REJECT "CTRL-EVENT-ASSOC-REJECT " +/** Authentication rejected during connection attempt */ +#define WPA_EVENT_AUTH_REJECT "CTRL-EVENT-AUTH-REJECT " +/** wpa_supplicant is exiting */ +#define WPA_EVENT_TERMINATING "CTRL-EVENT-TERMINATING " +/** Password change was completed successfully */ +#define WPA_EVENT_PASSWORD_CHANGED "CTRL-EVENT-PASSWORD-CHANGED " +/** EAP-Request/Notification received */ +#define WPA_EVENT_EAP_NOTIFICATION "CTRL-EVENT-EAP-NOTIFICATION " +/** EAP authentication started (EAP-Request/Identity received) */ +#define WPA_EVENT_EAP_STARTED "CTRL-EVENT-EAP-STARTED " +/** EAP method proposed by the server */ +#define WPA_EVENT_EAP_PROPOSED_METHOD "CTRL-EVENT-EAP-PROPOSED-METHOD " +/** EAP method selected */ +#define WPA_EVENT_EAP_METHOD "CTRL-EVENT-EAP-METHOD " +/** EAP peer certificate from TLS */ +#define WPA_EVENT_EAP_PEER_CERT "CTRL-EVENT-EAP-PEER-CERT " +/** EAP peer certificate alternative subject name component from TLS */ +#define WPA_EVENT_EAP_PEER_ALT "CTRL-EVENT-EAP-PEER-ALT " +/** EAP TLS certificate chain validation error */ +#define WPA_EVENT_EAP_TLS_CERT_ERROR "CTRL-EVENT-EAP-TLS-CERT-ERROR " +/** EAP status */ +#define WPA_EVENT_EAP_STATUS "CTRL-EVENT-EAP-STATUS " +/** Retransmit the previous request packet */ +#define WPA_EVENT_EAP_RETRANSMIT "CTRL-EVENT-EAP-RETRANSMIT " +#define WPA_EVENT_EAP_RETRANSMIT2 "CTRL-EVENT-EAP-RETRANSMIT2 " +/** EAP authentication completed successfully */ +#define WPA_EVENT_EAP_SUCCESS "CTRL-EVENT-EAP-SUCCESS " +#define WPA_EVENT_EAP_SUCCESS2 "CTRL-EVENT-EAP-SUCCESS2 " +/** EAP authentication failed (EAP-Failure received) */ +#define WPA_EVENT_EAP_FAILURE "CTRL-EVENT-EAP-FAILURE " +#define WPA_EVENT_EAP_FAILURE2 "CTRL-EVENT-EAP-FAILURE2 " +/** EAP authentication failed due to no response received */ +#define WPA_EVENT_EAP_TIMEOUT_FAILURE "CTRL-EVENT-EAP-TIMEOUT-FAILURE " +#define WPA_EVENT_EAP_TIMEOUT_FAILURE2 "CTRL-EVENT-EAP-TIMEOUT-FAILURE2 " +#define WPA_EVENT_EAP_ERROR_CODE "EAP-ERROR-CODE " +/** Network block temporarily disabled (e.g., due to authentication failure) */ +#define WPA_EVENT_TEMP_DISABLED "CTRL-EVENT-SSID-TEMP-DISABLED " +/** Temporarily disabled network block re-enabled */ +#define WPA_EVENT_REENABLED "CTRL-EVENT-SSID-REENABLED " +/** New scan started */ +#define WPA_EVENT_SCAN_STARTED "CTRL-EVENT-SCAN-STARTED " +/** New scan results available */ +#define WPA_EVENT_SCAN_RESULTS "CTRL-EVENT-SCAN-RESULTS " +/** Scan command failed */ +#define WPA_EVENT_SCAN_FAILED "CTRL-EVENT-SCAN-FAILED " +/** wpa_supplicant state change */ +#define WPA_EVENT_STATE_CHANGE "CTRL-EVENT-STATE-CHANGE " +/** A new BSS entry was added (followed by BSS entry id and BSSID) */ +#define WPA_EVENT_BSS_ADDED "CTRL-EVENT-BSS-ADDED " +/** A BSS entry was removed (followed by BSS entry id and BSSID) */ +#define WPA_EVENT_BSS_REMOVED "CTRL-EVENT-BSS-REMOVED " +/** No suitable network was found */ +#define WPA_EVENT_NETWORK_NOT_FOUND "CTRL-EVENT-NETWORK-NOT-FOUND " +/** Change in the signal level was reported by the driver */ +#define WPA_EVENT_SIGNAL_CHANGE "CTRL-EVENT-SIGNAL-CHANGE " +/** Beacon loss reported by the driver */ +#define WPA_EVENT_BEACON_LOSS "CTRL-EVENT-BEACON-LOSS " +/** Regulatory domain channel */ +#define WPA_EVENT_REGDOM_CHANGE "CTRL-EVENT-REGDOM-CHANGE " +/** Channel switch started (followed by freq= and other channel parameters) + */ +#define WPA_EVENT_CHANNEL_SWITCH_STARTED "CTRL-EVENT-STARTED-CHANNEL-SWITCH " +/** Channel switch (followed by freq= and other channel parameters) */ +#define WPA_EVENT_CHANNEL_SWITCH "CTRL-EVENT-CHANNEL-SWITCH " +/** SAE authentication failed due to unknown password identifier */ +#define WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER \ + "CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER " +/** Unprotected Beacon frame dropped */ +#define WPA_EVENT_UNPROT_BEACON "CTRL-EVENT-UNPROT-BEACON " +/** Decision made to do a within-ESS roam */ +#define WPA_EVENT_DO_ROAM "CTRL-EVENT-DO-ROAM " +/** Decision made to skip a within-ESS roam */ +#define WPA_EVENT_SKIP_ROAM "CTRL-EVENT-SKIP-ROAM " + +/** IP subnet status change notification + * + * When using an offloaded roaming mechanism where driver/firmware takes care + * of roaming and IP subnet validation checks post-roaming, this event can + * indicate whether IP subnet has changed. + * + * The event has a status=<0/1/2> parameter where + * 0 = unknown + * 1 = IP subnet unchanged (can continue to use the old IP address) + * 2 = IP subnet changed (need to get a new IP address) + */ +#define WPA_EVENT_SUBNET_STATUS_UPDATE "CTRL-EVENT-SUBNET-STATUS-UPDATE " + +/** RSN IBSS 4-way handshakes completed with specified peer */ +#define IBSS_RSN_COMPLETED "IBSS-RSN-COMPLETED " + +/** Notification of frequency conflict due to a concurrent operation. + * + * The indicated network is disabled and needs to be re-enabled before it can + * be used again. + */ +#define WPA_EVENT_FREQ_CONFLICT "CTRL-EVENT-FREQ-CONFLICT " +/** Frequency ranges that the driver recommends to avoid */ +#define WPA_EVENT_AVOID_FREQ "CTRL-EVENT-AVOID-FREQ " +/** A new network profile was added (followed by network entry id) */ +#define WPA_EVENT_NETWORK_ADDED "CTRL-EVENT-NETWORK-ADDED " +/** A network profile was removed (followed by prior network entry id) */ +#define WPA_EVENT_NETWORK_REMOVED "CTRL-EVENT-NETWORK-REMOVED " +/** Result of MSCS setup */ +#define WPA_EVENT_MSCS_RESULT "CTRL-EVENT-MSCS-RESULT " +/** WPS overlap detected in PBC mode */ +#define WPS_EVENT_OVERLAP "WPS-OVERLAP-DETECTED " +/** Available WPS AP with active PBC found in scan results */ +#define WPS_EVENT_AP_AVAILABLE_PBC "WPS-AP-AVAILABLE-PBC " +/** Available WPS AP with our address as authorized in scan results */ +#define WPS_EVENT_AP_AVAILABLE_AUTH "WPS-AP-AVAILABLE-AUTH " +/** Available WPS AP with recently selected PIN registrar found in scan results + */ +#define WPS_EVENT_AP_AVAILABLE_PIN "WPS-AP-AVAILABLE-PIN " +/** Available WPS AP found in scan results */ +#define WPS_EVENT_AP_AVAILABLE "WPS-AP-AVAILABLE " +/** A new credential received */ +#define WPS_EVENT_CRED_RECEIVED "WPS-CRED-RECEIVED " +/** M2D received */ +#define WPS_EVENT_M2D "WPS-M2D " +/** WPS registration failed after M2/M2D */ +#define WPS_EVENT_FAIL "WPS-FAIL " +/** WPS registration completed successfully */ +#define WPS_EVENT_SUCCESS "WPS-SUCCESS " +/** WPS enrollment attempt timed out and was terminated */ +#define WPS_EVENT_TIMEOUT "WPS-TIMEOUT " +/* PBC mode was activated */ +#define WPS_EVENT_ACTIVE "WPS-PBC-ACTIVE " +/* PBC mode was disabled */ +#define WPS_EVENT_DISABLE "WPS-PBC-DISABLE " + +#define WPS_EVENT_ENROLLEE_SEEN "WPS-ENROLLEE-SEEN " + +#define WPS_EVENT_OPEN_NETWORK "WPS-OPEN-NETWORK " +/** Result of SCS setup */ +#define WPA_EVENT_SCS_RESULT "CTRL-EVENT-SCS-RESULT " +/* Event indicating DSCP policy */ +#define WPA_EVENT_DSCP_POLICY "CTRL-EVENT-DSCP-POLICY " + +/* WPS ER events */ +#define WPS_EVENT_ER_AP_ADD "WPS-ER-AP-ADD " +#define WPS_EVENT_ER_AP_REMOVE "WPS-ER-AP-REMOVE " +#define WPS_EVENT_ER_ENROLLEE_ADD "WPS-ER-ENROLLEE-ADD " +#define WPS_EVENT_ER_ENROLLEE_REMOVE "WPS-ER-ENROLLEE-REMOVE " +#define WPS_EVENT_ER_AP_SETTINGS "WPS-ER-AP-SETTINGS " +#define WPS_EVENT_ER_SET_SEL_REG "WPS-ER-AP-SET-SEL-REG " + +/* DPP events */ +#define DPP_EVENT_AUTH_SUCCESS "DPP-AUTH-SUCCESS " +#define DPP_EVENT_AUTH_INIT_FAILED "DPP-AUTH-INIT-FAILED " +#define DPP_EVENT_NOT_COMPATIBLE "DPP-NOT-COMPATIBLE " +#define DPP_EVENT_RESPONSE_PENDING "DPP-RESPONSE-PENDING " +#define DPP_EVENT_SCAN_PEER_QR_CODE "DPP-SCAN-PEER-QR-CODE " +#define DPP_EVENT_AUTH_DIRECTION "DPP-AUTH-DIRECTION " +#define DPP_EVENT_CONF_RECEIVED "DPP-CONF-RECEIVED " +#define DPP_EVENT_CONF_SENT "DPP-CONF-SENT " +#define DPP_EVENT_CONF_FAILED "DPP-CONF-FAILED " +#define DPP_EVENT_CONN_STATUS_RESULT "DPP-CONN-STATUS-RESULT " +#define DPP_EVENT_CONFOBJ_AKM "DPP-CONFOBJ-AKM " +#define DPP_EVENT_CONFOBJ_SSID "DPP-CONFOBJ-SSID " +#define DPP_EVENT_CONFOBJ_SSID_CHARSET "DPP-CONFOBJ-SSID-CHARSET " +#define DPP_EVENT_CONFOBJ_PASS "DPP-CONFOBJ-PASS " +#define DPP_EVENT_CONFOBJ_PSK "DPP-CONFOBJ-PSK " +#define DPP_EVENT_CONNECTOR "DPP-CONNECTOR " +#define DPP_EVENT_C_SIGN_KEY "DPP-C-SIGN-KEY " +#define DPP_EVENT_PP_KEY "DPP-PP-KEY " +#define DPP_EVENT_NET_ACCESS_KEY "DPP-NET-ACCESS-KEY " +#define DPP_EVENT_SERVER_NAME "DPP-SERVER-NAME " +#define DPP_EVENT_CERTBAG "DPP-CERTBAG " +#define DPP_EVENT_CACERT "DPP-CACERT " +#define DPP_EVENT_MISSING_CONNECTOR "DPP-MISSING-CONNECTOR " +#define DPP_EVENT_NETWORK_ID "DPP-NETWORK-ID " +#define DPP_EVENT_CONFIGURATOR_ID "DPP-CONFIGURATOR-ID " +#define DPP_EVENT_RX "DPP-RX " +#define DPP_EVENT_TX "DPP-TX " +#define DPP_EVENT_TX_STATUS "DPP-TX-STATUS " +#define DPP_EVENT_FAIL "DPP-FAIL " +#define DPP_EVENT_PKEX_T_LIMIT "DPP-PKEX-T-LIMIT " +#define DPP_EVENT_INTRO "DPP-INTRO " +#define DPP_EVENT_CONF_REQ_RX "DPP-CONF-REQ-RX " +#define DPP_EVENT_CHIRP_STOPPED "DPP-CHIRP-STOPPED " +#define DPP_EVENT_MUD_URL "DPP-MUD-URL " +#define DPP_EVENT_BAND_SUPPORT "DPP-BAND-SUPPORT " +#define DPP_EVENT_CSR "DPP-CSR " +#define DPP_EVENT_CHIRP_RX "DPP-CHIRP-RX " + +/* MESH events */ +#define MESH_GROUP_STARTED "MESH-GROUP-STARTED " +#define MESH_GROUP_REMOVED "MESH-GROUP-REMOVED " +#define MESH_PEER_CONNECTED "MESH-PEER-CONNECTED " +#define MESH_PEER_DISCONNECTED "MESH-PEER-DISCONNECTED " +/** Mesh SAE authentication failure. Wrong password suspected. */ +#define MESH_SAE_AUTH_FAILURE "MESH-SAE-AUTH-FAILURE " +#define MESH_SAE_AUTH_BLOCKED "MESH-SAE-AUTH-BLOCKED " + +/* WMM AC events */ +#define WMM_AC_EVENT_TSPEC_ADDED "TSPEC-ADDED " +#define WMM_AC_EVENT_TSPEC_REMOVED "TSPEC-REMOVED " +#define WMM_AC_EVENT_TSPEC_REQ_FAILED "TSPEC-REQ-FAILED " + +/** P2P device found */ +#define P2P_EVENT_DEVICE_FOUND "P2P-DEVICE-FOUND " + +/** P2P device lost */ +#define P2P_EVENT_DEVICE_LOST "P2P-DEVICE-LOST " + +/** A P2P device requested GO negotiation, but we were not ready to start the + * negotiation */ +#define P2P_EVENT_GO_NEG_REQUEST "P2P-GO-NEG-REQUEST " +#define P2P_EVENT_GO_NEG_SUCCESS "P2P-GO-NEG-SUCCESS " +#define P2P_EVENT_GO_NEG_FAILURE "P2P-GO-NEG-FAILURE " +#define P2P_EVENT_GROUP_FORMATION_SUCCESS "P2P-GROUP-FORMATION-SUCCESS " +#define P2P_EVENT_GROUP_FORMATION_FAILURE "P2P-GROUP-FORMATION-FAILURE " +#define P2P_EVENT_GROUP_STARTED "P2P-GROUP-STARTED " +#define P2P_EVENT_GROUP_REMOVED "P2P-GROUP-REMOVED " +#define P2P_EVENT_CROSS_CONNECT_ENABLE "P2P-CROSS-CONNECT-ENABLE " +#define P2P_EVENT_CROSS_CONNECT_DISABLE "P2P-CROSS-CONNECT-DISABLE " +/* parameters: */ +#define P2P_EVENT_PROV_DISC_SHOW_PIN "P2P-PROV-DISC-SHOW-PIN " +/* parameters: */ +#define P2P_EVENT_PROV_DISC_ENTER_PIN "P2P-PROV-DISC-ENTER-PIN " +/* parameters: */ +#define P2P_EVENT_PROV_DISC_PBC_REQ "P2P-PROV-DISC-PBC-REQ " +/* parameters: */ +#define P2P_EVENT_PROV_DISC_PBC_RESP "P2P-PROV-DISC-PBC-RESP " +/* parameters: */ +#define P2P_EVENT_PROV_DISC_FAILURE "P2P-PROV-DISC-FAILURE" +/* parameters: */ +#define P2P_EVENT_SERV_DISC_REQ "P2P-SERV-DISC-REQ " +/* parameters: */ +#define P2P_EVENT_SERV_DISC_RESP "P2P-SERV-DISC-RESP " +#define P2P_EVENT_SERV_ASP_RESP "P2P-SERV-ASP-RESP " +#define P2P_EVENT_INVITATION_RECEIVED "P2P-INVITATION-RECEIVED " +#define P2P_EVENT_INVITATION_RESULT "P2P-INVITATION-RESULT " +#define P2P_EVENT_INVITATION_ACCEPTED "P2P-INVITATION-ACCEPTED " +#define P2P_EVENT_FIND_STOPPED "P2P-FIND-STOPPED " +#define P2P_EVENT_PERSISTENT_PSK_FAIL "P2P-PERSISTENT-PSK-FAIL id=" +#define P2P_EVENT_PRESENCE_RESPONSE "P2P-PRESENCE-RESPONSE " +#define P2P_EVENT_NFC_BOTH_GO "P2P-NFC-BOTH-GO " +#define P2P_EVENT_NFC_PEER_CLIENT "P2P-NFC-PEER-CLIENT " +#define P2P_EVENT_NFC_WHILE_CLIENT "P2P-NFC-WHILE-CLIENT " +#define P2P_EVENT_FALLBACK_TO_GO_NEG "P2P-FALLBACK-TO-GO-NEG " +#define P2P_EVENT_FALLBACK_TO_GO_NEG_ENABLED "P2P-FALLBACK-TO-GO-NEG-ENABLED " + +/* parameters: */ +#define ESS_DISASSOC_IMMINENT "ESS-DISASSOC-IMMINENT " +#define P2P_EVENT_REMOVE_AND_REFORM_GROUP "P2P-REMOVE-AND-REFORM-GROUP " + +#define P2P_EVENT_P2PS_PROVISION_START "P2PS-PROV-START " +#define P2P_EVENT_P2PS_PROVISION_DONE "P2PS-PROV-DONE " + +#define INTERWORKING_AP "INTERWORKING-AP " +#define INTERWORKING_EXCLUDED "INTERWORKING-BLACKLISTED " +#define INTERWORKING_NO_MATCH "INTERWORKING-NO-MATCH " +#define INTERWORKING_ALREADY_CONNECTED "INTERWORKING-ALREADY-CONNECTED " +#define INTERWORKING_SELECTED "INTERWORKING-SELECTED " + +/* Credential block added; parameters: */ +#define CRED_ADDED "CRED-ADDED " +/* Credential block modified; parameters: */ +#define CRED_MODIFIED "CRED-MODIFIED " +/* Credential block removed; parameters: */ +#define CRED_REMOVED "CRED-REMOVED " + +#define GAS_RESPONSE_INFO "GAS-RESPONSE-INFO " +/* parameters: */ +#define GAS_QUERY_START "GAS-QUERY-START " +/* parameters: */ +#define GAS_QUERY_DONE "GAS-QUERY-DONE " + +/* parameters: */ +#define ANQP_QUERY_DONE "ANQP-QUERY-DONE " + +#define RX_ANQP "RX-ANQP " +#define RX_HS20_ANQP "RX-HS20-ANQP " +#define RX_HS20_ANQP_ICON "RX-HS20-ANQP-ICON " +#define RX_HS20_ICON "RX-HS20-ICON " +#define RX_MBO_ANQP "RX-MBO-ANQP " + +/* parameters: */ +#define RX_VENUE_URL "RX-VENUE-URL " + +#define HS20_SUBSCRIPTION_REMEDIATION "HS20-SUBSCRIPTION-REMEDIATION " +#define HS20_DEAUTH_IMMINENT_NOTICE "HS20-DEAUTH-IMMINENT-NOTICE " +#define HS20_T_C_ACCEPTANCE "HS20-T-C-ACCEPTANCE " + +#define EXT_RADIO_WORK_START "EXT-RADIO-WORK-START " +#define EXT_RADIO_WORK_TIMEOUT "EXT-RADIO-WORK-TIMEOUT " + +#define RRM_EVENT_NEIGHBOR_REP_RXED "RRM-NEIGHBOR-REP-RECEIVED " +#define RRM_EVENT_NEIGHBOR_REP_FAILED "RRM-NEIGHBOR-REP-REQUEST-FAILED " + +/* hostapd control interface - fixed message prefixes */ +#define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED " +#define WPS_EVENT_NEW_AP_SETTINGS "WPS-NEW-AP-SETTINGS " +#define WPS_EVENT_REG_SUCCESS "WPS-REG-SUCCESS " +#define WPS_EVENT_AP_SETUP_LOCKED "WPS-AP-SETUP-LOCKED " +#define WPS_EVENT_AP_SETUP_UNLOCKED "WPS-AP-SETUP-UNLOCKED " +#define WPS_EVENT_AP_PIN_ENABLED "WPS-AP-PIN-ENABLED " +#define WPS_EVENT_AP_PIN_DISABLED "WPS-AP-PIN-DISABLED " +#define WPS_EVENT_PIN_ACTIVE "WPS-PIN-ACTIVE " +#define WPS_EVENT_CANCEL "WPS-CANCEL " +#define AP_STA_CONNECTED "AP-STA-CONNECTED " +#define AP_STA_DISCONNECTED "AP-STA-DISCONNECTED " +#define AP_STA_POSSIBLE_PSK_MISMATCH "AP-STA-POSSIBLE-PSK-MISMATCH " +#define AP_STA_POLL_OK "AP-STA-POLL-OK " + +#define AP_REJECTED_MAX_STA "AP-REJECTED-MAX-STA " +#define AP_REJECTED_BLOCKED_STA "AP-REJECTED-BLOCKED-STA " + +#define HS20_T_C_FILTERING_ADD "HS20-T-C-FILTERING-ADD " +#define HS20_T_C_FILTERING_REMOVE "HS20-T-C-FILTERING-REMOVE " + +#define AP_EVENT_ENABLED "AP-ENABLED " +#define AP_EVENT_DISABLED "AP-DISABLED " + +#define INTERFACE_ENABLED "INTERFACE-ENABLED " +#define INTERFACE_DISABLED "INTERFACE-DISABLED " + +#define ACS_EVENT_STARTED "ACS-STARTED " +#define ACS_EVENT_COMPLETED "ACS-COMPLETED " +#define ACS_EVENT_FAILED "ACS-FAILED " + +#define DFS_EVENT_RADAR_DETECTED "DFS-RADAR-DETECTED " +#define DFS_EVENT_NEW_CHANNEL "DFS-NEW-CHANNEL " +#define DFS_EVENT_CAC_START "DFS-CAC-START " +#define DFS_EVENT_CAC_COMPLETED "DFS-CAC-COMPLETED " +#define DFS_EVENT_NOP_FINISHED "DFS-NOP-FINISHED " +#define DFS_EVENT_PRE_CAC_EXPIRED "DFS-PRE-CAC-EXPIRED " + +#define AP_CSA_FINISHED "AP-CSA-FINISHED " + +#define P2P_EVENT_LISTEN_OFFLOAD_STOP "P2P-LISTEN-OFFLOAD-STOPPED " +#define P2P_LISTEN_OFFLOAD_STOP_REASON "P2P-LISTEN-OFFLOAD-STOP-REASON " + +/* BSS Transition Management Response frame received */ +#define BSS_TM_RESP "BSS-TM-RESP " + +/* Collocated Interference Request frame received; + * parameters: */ +#define COLOC_INTF_REQ "COLOC-INTF-REQ " +/* Collocated Interference Report frame received; + * parameters: */ +#define COLOC_INTF_REPORT "COLOC-INTF-REPORT " + +/* MBO IE with cellular data connection preference received */ +#define MBO_CELL_PREFERENCE "MBO-CELL-PREFERENCE " + +/* BSS Transition Management Request received with MBO transition reason */ +#define MBO_TRANSITION_REASON "MBO-TRANSITION-REASON " + +/* parameters: */ +#define BEACON_REQ_TX_STATUS "BEACON-REQ-TX-STATUS " +/* parameters: */ +#define BEACON_RESP_RX "BEACON-RESP-RX " + +/* PMKSA cache entry added; parameters: */ +#define PMKSA_CACHE_ADDED "PMKSA-CACHE-ADDED " +/* PMKSA cache entry removed; parameters: */ +#define PMKSA_CACHE_REMOVED "PMKSA-CACHE-REMOVED " + +/* FILS HLP Container receive; parameters: dst= src= frame= + */ +#define FILS_HLP_RX "FILS-HLP-RX " + +/* Event to indicate Probe Request frame; + * parameters: sa= signal= */ +#define RX_PROBE_REQUEST "RX-PROBE-REQUEST " + +/* Event to indicate station's HT/VHT operation mode change information */ +#define STA_OPMODE_MAX_BW_CHANGED "STA-OPMODE-MAX-BW-CHANGED " +#define STA_OPMODE_SMPS_MODE_CHANGED "STA-OPMODE-SMPS-MODE-CHANGED " +#define STA_OPMODE_N_SS_CHANGED "STA-OPMODE-N_SS-CHANGED " + +/* New interface addition or removal for 4addr WDS SDA */ +#define WDS_STA_INTERFACE_ADDED "WDS-STA-INTERFACE-ADDED " +#define WDS_STA_INTERFACE_REMOVED "WDS-STA-INTERFACE-REMOVED " + +/* Transition mode disabled indication - followed by bitmap */ +#define TRANSITION_DISABLE "TRANSITION-DISABLE " + +/* OCV validation failure; parameters: addr= + * frame= error= */ +#define OCV_FAILURE "OCV-FAILURE " + +/* Event triggered for received management frame */ +#define AP_MGMT_FRAME_RECEIVED "AP-MGMT-FRAME-RECEIVED " + +#ifndef BIT +#define BIT(x) (1U << (x)) +#endif + +/* PASN authentication status */ +#define PASN_AUTH_STATUS "PASN-AUTH-STATUS " + +/* BSS command information masks */ + +#define WPA_BSS_MASK_ALL 0xFFFDFFFF +#define WPA_BSS_MASK_ID BIT(0) +#define WPA_BSS_MASK_BSSID BIT(1) +#define WPA_BSS_MASK_FREQ BIT(2) +#define WPA_BSS_MASK_BEACON_INT BIT(3) +#define WPA_BSS_MASK_CAPABILITIES BIT(4) +#define WPA_BSS_MASK_QUAL BIT(5) +#define WPA_BSS_MASK_NOISE BIT(6) +#define WPA_BSS_MASK_LEVEL BIT(7) +#define WPA_BSS_MASK_TSF BIT(8) +#define WPA_BSS_MASK_AGE BIT(9) +#define WPA_BSS_MASK_IE BIT(10) +#define WPA_BSS_MASK_FLAGS BIT(11) +#define WPA_BSS_MASK_SSID BIT(12) +#define WPA_BSS_MASK_WPS_SCAN BIT(13) +#define WPA_BSS_MASK_P2P_SCAN BIT(14) +#define WPA_BSS_MASK_INTERNETW BIT(15) +#define WPA_BSS_MASK_WIFI_DISPLAY BIT(16) +#define WPA_BSS_MASK_DELIM BIT(17) +#define WPA_BSS_MASK_MESH_SCAN BIT(18) +#define WPA_BSS_MASK_SNR BIT(19) +#define WPA_BSS_MASK_EST_THROUGHPUT BIT(20) +#define WPA_BSS_MASK_FST BIT(21) +#define WPA_BSS_MASK_UPDATE_IDX BIT(22) +#define WPA_BSS_MASK_BEACON_IE BIT(23) +#define WPA_BSS_MASK_FILS_INDICATION BIT(24) + + +/* VENDOR_ELEM_* frame id values */ +enum wpa_vendor_elem_frame { + VENDOR_ELEM_PROBE_REQ_P2P = 0, + VENDOR_ELEM_PROBE_RESP_P2P = 1, + VENDOR_ELEM_PROBE_RESP_P2P_GO = 2, + VENDOR_ELEM_BEACON_P2P_GO = 3, + VENDOR_ELEM_P2P_PD_REQ = 4, + VENDOR_ELEM_P2P_PD_RESP = 5, + VENDOR_ELEM_P2P_GO_NEG_REQ = 6, + VENDOR_ELEM_P2P_GO_NEG_RESP = 7, + VENDOR_ELEM_P2P_GO_NEG_CONF = 8, + VENDOR_ELEM_P2P_INV_REQ = 9, + VENDOR_ELEM_P2P_INV_RESP = 10, + VENDOR_ELEM_P2P_ASSOC_REQ = 11, + VENDOR_ELEM_P2P_ASSOC_RESP = 12, + VENDOR_ELEM_ASSOC_REQ = 13, + VENDOR_ELEM_PROBE_REQ = 14, + NUM_VENDOR_ELEM_FRAMES +}; + + +/* wpa_supplicant/hostapd control interface access */ + +/** + * wpa_ctrl_open - Open a control interface to wpa_supplicant/hostapd + * @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used. + * Returns: Pointer to abstract control interface data or %NULL on failure + * + * This function is used to open a control interface to wpa_supplicant/hostapd. + * ctrl_path is usually /var/run/wpa_supplicant or /var/run/hostapd. This path + * is configured in wpa_supplicant/hostapd and other programs using the control + * interface need to use matching path configuration. + */ +struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path); + +/** + * wpa_ctrl_open2 - Open a control interface to wpa_supplicant/hostapd + * @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used. + * @cli_path: Path for client UNIX domain sockets; ignored if UDP socket + * is used. + * Returns: Pointer to abstract control interface data or %NULL on failure + * + * This function is used to open a control interface to wpa_supplicant/hostapd + * when the socket path for client need to be specified explicitly. Default + * ctrl_path is usually /var/run/wpa_supplicant or /var/run/hostapd and client + * socket path is /tmp. + */ +struct wpa_ctrl * wpa_ctrl_open2(const char *ctrl_path, const char *cli_path); + + +/** + * wpa_ctrl_close - Close a control interface to wpa_supplicant/hostapd + * @ctrl: Control interface data from wpa_ctrl_open() + * + * This function is used to close a control interface. + */ +void wpa_ctrl_close(struct wpa_ctrl *ctrl); + + +/** + * wpa_ctrl_request - Send a command to wpa_supplicant/hostapd + * @ctrl: Control interface data from wpa_ctrl_open() + * @cmd: Command; usually, ASCII text, e.g., "PING" + * @cmd_len: Length of the cmd in bytes + * @reply: Buffer for the response + * @reply_len: Reply buffer length + * @msg_cb: Callback function for unsolicited messages or %NULL if not used + * Returns: 0 on success, -1 on error (send or receive failed), -2 on timeout + * + * This function is used to send commands to wpa_supplicant/hostapd. Received + * response will be written to reply and reply_len is set to the actual length + * of the reply. This function will block for up to 10 seconds while waiting + * for the reply. If unsolicited messages are received, the blocking time may + * be longer. + * + * msg_cb can be used to register a callback function that will be called for + * unsolicited messages received while waiting for the command response. These + * messages may be received if wpa_ctrl_request() is called at the same time as + * wpa_supplicant/hostapd is sending such a message. This can happen only if + * the program has used wpa_ctrl_attach() to register itself as a monitor for + * event messages. Alternatively to msg_cb, programs can register two control + * interface connections and use one of them for commands and the other one for + * receiving event messages, in other words, call wpa_ctrl_attach() only for + * the control interface connection that will be used for event messages. + */ +int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len, + char *reply, size_t *reply_len, + void (*msg_cb)(char *msg, size_t len)); + + +/** + * wpa_ctrl_attach - Register as an event monitor for the control interface + * @ctrl: Control interface data from wpa_ctrl_open() + * Returns: 0 on success, -1 on failure, -2 on timeout + * + * This function registers the control interface connection as a monitor for + * wpa_supplicant/hostapd events. After a success wpa_ctrl_attach() call, the + * control interface connection starts receiving event messages that can be + * read with wpa_ctrl_recv(). + */ +int wpa_ctrl_attach(struct wpa_ctrl *ctrl); + + +/** + * wpa_ctrl_detach - Unregister event monitor from the control interface + * @ctrl: Control interface data from wpa_ctrl_open() + * Returns: 0 on success, -1 on failure, -2 on timeout + * + * This function unregisters the control interface connection as a monitor for + * wpa_supplicant/hostapd events, i.e., cancels the registration done with + * wpa_ctrl_attach(). + */ +int wpa_ctrl_detach(struct wpa_ctrl *ctrl); + + +/** + * wpa_ctrl_recv - Receive a pending control interface message + * @ctrl: Control interface data from wpa_ctrl_open() + * @reply: Buffer for the message data + * @reply_len: Length of the reply buffer + * Returns: 0 on success, -1 on failure + * + * This function will receive a pending control interface message. The received + * response will be written to reply and reply_len is set to the actual length + * of the reply. + + * wpa_ctrl_recv() is only used for event messages, i.e., wpa_ctrl_attach() + * must have been used to register the control interface as an event monitor. + */ +int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len); + + +/** + * wpa_ctrl_pending - Check whether there are pending event messages + * @ctrl: Control interface data from wpa_ctrl_open() + * Returns: 1 if there are pending messages, 0 if no, or -1 on error + * + * This function will check whether there are any pending control interface + * message available to be received with wpa_ctrl_recv(). wpa_ctrl_pending() is + * only used for event messages, i.e., wpa_ctrl_attach() must have been used to + * register the control interface as an event monitor. + */ +int wpa_ctrl_pending(struct wpa_ctrl *ctrl); + + +/** + * wpa_ctrl_get_fd - Get file descriptor used by the control interface + * @ctrl: Control interface data from wpa_ctrl_open() + * Returns: File descriptor used for the connection + * + * This function can be used to get the file descriptor that is used for the + * control interface connection. The returned value can be used, e.g., with + * select() while waiting for multiple events. + * + * The returned file descriptor must not be used directly for sending or + * receiving packets; instead, the library functions wpa_ctrl_request() and + * wpa_ctrl_recv() must be used for this. + */ +int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl); + +#ifdef ANDROID +/** + * wpa_ctrl_cleanup() - Delete any local UNIX domain socket files that + * may be left over from clients that were previously connected to + * wpa_supplicant. This keeps these files from being orphaned in the + * event of crashes that prevented them from being removed as part + * of the normal orderly shutdown. + */ +void wpa_ctrl_cleanup(void); +#endif /* ANDROID */ + +#ifdef CONFIG_CTRL_IFACE_UDP +/* Port range for multiple wpa_supplicant instances and multiple VIFs */ +#define WPA_CTRL_IFACE_PORT 9877 +#define WPA_CTRL_IFACE_PORT_LIMIT 50 /* decremented from start */ +#define WPA_GLOBAL_CTRL_IFACE_PORT 9878 +#define WPA_GLOBAL_CTRL_IFACE_PORT_LIMIT 20 /* incremented from start */ + +char * wpa_ctrl_get_remote_ifname(struct wpa_ctrl *ctrl); +#endif /* CONFIG_CTRL_IFACE_UDP */ + + +#ifdef __cplusplus +} +#endif + +#endif /* WPA_CTRL_H */ diff --git a/lib/nif/wpa_supplicant/wpa_debug.h b/lib/nif/wpa_supplicant/wpa_debug.h new file mode 100644 index 0000000..c6d5cc6 --- /dev/null +++ b/lib/nif/wpa_supplicant/wpa_debug.h @@ -0,0 +1,370 @@ +/* + * wpa_supplicant/hostapd / Debug prints + * Copyright (c) 2002-2013, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef WPA_DEBUG_H +#define WPA_DEBUG_H + +#include "wpabuf.h" + +extern int wpa_debug_level; +extern int wpa_debug_show_keys; +extern int wpa_debug_timestamp; +extern int wpa_debug_syslog; + +/* Debugging function - conditional printf and hex dump. Driver wrappers can + * use these for debugging purposes. */ + +enum { + MSG_EXCESSIVE, MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR +}; + +#ifdef CONFIG_NO_STDOUT_DEBUG + +#define wpa_debug_print_timestamp() do { } while (0) +#define wpa_printf(args...) do { } while (0) +#define wpa_hexdump(l,t,b,le) do { } while (0) +#define wpa_hexdump_buf(l,t,b) do { } while (0) +#define wpa_hexdump_key(l,t,b,le) do { } while (0) +#define wpa_hexdump_buf_key(l,t,b) do { } while (0) +#define wpa_hexdump_ascii(l,t,b,le) do { } while (0) +#define wpa_hexdump_ascii_key(l,t,b,le) do { } while (0) +#define wpa_debug_open_file(p) do { } while (0) +#define wpa_debug_close_file() do { } while (0) +#define wpa_debug_setup_stdout() do { } while (0) +#define wpa_dbg(args...) do { } while (0) + +static inline int wpa_debug_reopen_file(void) +{ + return 0; +} + +#else /* CONFIG_NO_STDOUT_DEBUG */ + +int wpa_debug_open_file(const char *path); +int wpa_debug_reopen_file(void); +void wpa_debug_close_file(void); +void wpa_debug_setup_stdout(void); + +/** + * wpa_debug_printf_timestamp - Print timestamp for debug output + * + * This function prints a timestamp in seconds_from_1970.microsoconds + * format if debug output has been configured to include timestamps in debug + * messages. + */ +void wpa_debug_print_timestamp(void); + +/** + * wpa_printf - conditional printf + * @level: priority level (MSG_*) of the message + * @fmt: printf format string, followed by optional arguments + * + * This function is used to print conditional debugging and error messages. The + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. + * + * Note: New line '\n' is added to the end of the text when printing to stdout. + */ +void wpa_printf(int level, const char *fmt, ...) +PRINTF_FORMAT(2, 3); + +/** + * wpa_hexdump - conditional hex dump + * @level: priority level (MSG_*) of the message + * @title: title of for the message + * @buf: data buffer to be dumped + * @len: length of the buf + * + * This function is used to print conditional debugging and error messages. The + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. The contents of buf is printed out has hex dump. + */ +void wpa_hexdump(int level, const char *title, const void *buf, size_t len); + +static inline void wpa_hexdump_buf(int level, const char *title, + const struct wpabuf *buf) +{ + wpa_hexdump(level, title, buf ? wpabuf_head(buf) : NULL, + buf ? wpabuf_len(buf) : 0); +} + +/** + * wpa_hexdump_key - conditional hex dump, hide keys + * @level: priority level (MSG_*) of the message + * @title: title of for the message + * @buf: data buffer to be dumped + * @len: length of the buf + * + * This function is used to print conditional debugging and error messages. The + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. The contents of buf is printed out has hex dump. This works + * like wpa_hexdump(), but by default, does not include secret keys (passwords, + * etc.) in debug output. + */ +void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len); + +static inline void wpa_hexdump_buf_key(int level, const char *title, + const struct wpabuf *buf) +{ + wpa_hexdump_key(level, title, buf ? wpabuf_head(buf) : NULL, + buf ? wpabuf_len(buf) : 0); +} + +/** + * wpa_hexdump_ascii - conditional hex dump + * @level: priority level (MSG_*) of the message + * @title: title of for the message + * @buf: data buffer to be dumped + * @len: length of the buf + * + * This function is used to print conditional debugging and error messages. The + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. The contents of buf is printed out has hex dump with both + * the hex numbers and ASCII characters (for printable range) are shown. 16 + * bytes per line will be shown. + */ +void wpa_hexdump_ascii(int level, const char *title, const void *buf, + size_t len); + +/** + * wpa_hexdump_ascii_key - conditional hex dump, hide keys + * @level: priority level (MSG_*) of the message + * @title: title of for the message + * @buf: data buffer to be dumped + * @len: length of the buf + * + * This function is used to print conditional debugging and error messages. The + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. The contents of buf is printed out has hex dump with both + * the hex numbers and ASCII characters (for printable range) are shown. 16 + * bytes per line will be shown. This works like wpa_hexdump_ascii(), but by + * default, does not include secret keys (passwords, etc.) in debug output. + */ +void wpa_hexdump_ascii_key(int level, const char *title, const void *buf, + size_t len); + +/* + * wpa_dbg() behaves like wpa_msg(), but it can be removed from build to reduce + * binary size. As such, it should be used with debugging messages that are not + * needed in the control interface while wpa_msg() has to be used for anything + * that needs to shown to control interface monitors. + */ +#define wpa_dbg(args...) wpa_msg(args) + +#endif /* CONFIG_NO_STDOUT_DEBUG */ + + +#ifdef CONFIG_NO_WPA_MSG +#define wpa_msg(args...) do { } while (0) +#define wpa_msg_ctrl(args...) do { } while (0) +#define wpa_msg_global(args...) do { } while (0) +#define wpa_msg_global_ctrl(args...) do { } while (0) +#define wpa_msg_no_global(args...) do { } while (0) +#define wpa_msg_global_only(args...) do { } while (0) +#define wpa_msg_register_cb(f) do { } while (0) +#define wpa_msg_register_ifname_cb(f) do { } while (0) +#else /* CONFIG_NO_WPA_MSG */ +/** + * wpa_msg - Conditional printf for default target and ctrl_iface monitors + * @ctx: Pointer to context data; this is the ctx variable registered + * with struct wpa_driver_ops::init() + * @level: priority level (MSG_*) of the message + * @fmt: printf format string, followed by optional arguments + * + * This function is used to print conditional debugging and error messages. The + * output may be directed to stdout, stderr, and/or syslog based on + * configuration. This function is like wpa_printf(), but it also sends the + * same message to all attached ctrl_iface monitors. + * + * Note: New line '\n' is added to the end of the text when printing to stdout. + */ +void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4); + +/** + * wpa_msg_ctrl - Conditional printf for ctrl_iface monitors + * @ctx: Pointer to context data; this is the ctx variable registered + * with struct wpa_driver_ops::init() + * @level: priority level (MSG_*) of the message + * @fmt: printf format string, followed by optional arguments + * + * This function is used to print conditional debugging and error messages. + * This function is like wpa_msg(), but it sends the output only to the + * attached ctrl_iface monitors. In other words, it can be used for frequent + * events that do not need to be sent to syslog. + */ +void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) +PRINTF_FORMAT(3, 4); + +/** + * wpa_msg_global - Global printf for ctrl_iface monitors + * @ctx: Pointer to context data; this is the ctx variable registered + * with struct wpa_driver_ops::init() + * @level: priority level (MSG_*) of the message + * @fmt: printf format string, followed by optional arguments + * + * This function is used to print conditional debugging and error messages. + * This function is like wpa_msg(), but it sends the output as a global event, + * i.e., without being specific to an interface. For backwards compatibility, + * an old style event is also delivered on one of the interfaces (the one + * specified by the context data). + */ +void wpa_msg_global(void *ctx, int level, const char *fmt, ...) +PRINTF_FORMAT(3, 4); + +/** + * wpa_msg_global_ctrl - Conditional global printf for ctrl_iface monitors + * @ctx: Pointer to context data; this is the ctx variable registered + * with struct wpa_driver_ops::init() + * @level: priority level (MSG_*) of the message + * @fmt: printf format string, followed by optional arguments + * + * This function is used to print conditional debugging and error messages. + * This function is like wpa_msg_global(), but it sends the output only to the + * attached global ctrl_iface monitors. In other words, it can be used for + * frequent events that do not need to be sent to syslog. + */ +void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...) +PRINTF_FORMAT(3, 4); + +/** + * wpa_msg_no_global - Conditional printf for ctrl_iface monitors + * @ctx: Pointer to context data; this is the ctx variable registered + * with struct wpa_driver_ops::init() + * @level: priority level (MSG_*) of the message + * @fmt: printf format string, followed by optional arguments + * + * This function is used to print conditional debugging and error messages. + * This function is like wpa_msg(), but it does not send the output as a global + * event. + */ +void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...) +PRINTF_FORMAT(3, 4); + +/** + * wpa_msg_global_only - Conditional printf for ctrl_iface monitors + * @ctx: Pointer to context data; this is the ctx variable registered + * with struct wpa_driver_ops::init() + * @level: priority level (MSG_*) of the message + * @fmt: printf format string, followed by optional arguments + * + * This function is used to print conditional debugging and error messages. + * This function is like wpa_msg_global(), but it sends the output only as a + * global event. + */ +void wpa_msg_global_only(void *ctx, int level, const char *fmt, ...) +PRINTF_FORMAT(3, 4); + +enum wpa_msg_type { + WPA_MSG_PER_INTERFACE, + WPA_MSG_GLOBAL, + WPA_MSG_NO_GLOBAL, + WPA_MSG_ONLY_GLOBAL, +}; + +typedef void (*wpa_msg_cb_func)(void *ctx, int level, enum wpa_msg_type type, + const char *txt, size_t len); + +/** + * wpa_msg_register_cb - Register callback function for wpa_msg() messages + * @func: Callback function (%NULL to unregister) + */ +void wpa_msg_register_cb(wpa_msg_cb_func func); + +typedef const char * (*wpa_msg_get_ifname_func)(void *ctx); +void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func); + +#endif /* CONFIG_NO_WPA_MSG */ + +#ifdef CONFIG_NO_HOSTAPD_LOGGER +#define hostapd_logger(args...) do { } while (0) +#define hostapd_logger_register_cb(f) do { } while (0) +#else /* CONFIG_NO_HOSTAPD_LOGGER */ +void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level, + const char *fmt, ...) PRINTF_FORMAT(5, 6); + +typedef void (*hostapd_logger_cb_func)(void *ctx, const u8 *addr, + unsigned int module, int level, + const char *txt, size_t len); + +/** + * hostapd_logger_register_cb - Register callback function for hostapd_logger() + * @func: Callback function (%NULL to unregister) + */ +void hostapd_logger_register_cb(hostapd_logger_cb_func func); +#endif /* CONFIG_NO_HOSTAPD_LOGGER */ + +#define HOSTAPD_MODULE_IEEE80211 0x00000001 +#define HOSTAPD_MODULE_IEEE8021X 0x00000002 +#define HOSTAPD_MODULE_RADIUS 0x00000004 +#define HOSTAPD_MODULE_WPA 0x00000008 +#define HOSTAPD_MODULE_DRIVER 0x00000010 +#define HOSTAPD_MODULE_MLME 0x00000040 + +enum hostapd_logger_level { + HOSTAPD_LEVEL_DEBUG_VERBOSE = 0, + HOSTAPD_LEVEL_DEBUG = 1, + HOSTAPD_LEVEL_INFO = 2, + HOSTAPD_LEVEL_NOTICE = 3, + HOSTAPD_LEVEL_WARNING = 4 +}; + + +#ifdef CONFIG_DEBUG_SYSLOG + +void wpa_debug_open_syslog(void); +void wpa_debug_close_syslog(void); + +#else /* CONFIG_DEBUG_SYSLOG */ + +static inline void wpa_debug_open_syslog(void) +{ +} + +static inline void wpa_debug_close_syslog(void) +{ +} + +#endif /* CONFIG_DEBUG_SYSLOG */ + +#ifdef CONFIG_DEBUG_LINUX_TRACING + +int wpa_debug_open_linux_tracing(void); +void wpa_debug_close_linux_tracing(void); + +#else /* CONFIG_DEBUG_LINUX_TRACING */ + +static inline int wpa_debug_open_linux_tracing(void) +{ + return 0; +} + +static inline void wpa_debug_close_linux_tracing(void) +{ +} + +#endif /* CONFIG_DEBUG_LINUX_TRACING */ + + +#ifdef EAPOL_TEST +#define WPA_ASSERT(a) \ + do { \ + if (!(a)) { \ + printf("WPA_ASSERT FAILED '" #a "' " \ + "%s %s:%d\n", \ + __FUNCTION__, __FILE__, __LINE__); \ + exit(1); \ + } \ + } while (0) +#else +#define WPA_ASSERT(a) do { } while (0) +#endif + +const char * debug_level_str(int level); +int str_to_debug_level(const char *s); + +#endif /* WPA_DEBUG_H */ diff --git a/lib/nif/wpa_supplicant/wpa_helpers.h b/lib/nif/wpa_supplicant/wpa_helpers.h new file mode 100644 index 0000000..266f454 --- /dev/null +++ b/lib/nif/wpa_supplicant/wpa_helpers.h @@ -0,0 +1,39 @@ +/* + * wpa_supplicant ctrl_iface helpers + * Copyright (c) 2010-2011, Atheros Communications, Inc. + * Copyright (c) 2011-2012, Qualcomm Atheros, Inc. + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef WPA_HELPERS_H +#define WPA_HELPERS_H + +#include + +int wpa_command(const char *ifname, const char *cmd); +int wpa_command_resp(const char *ifname, const char *cmd, + char *resp, size_t resp_size); +int get_wpa_status(const char *ifname, const char *field, char *obuf, + size_t obuf_size); + +struct wpa_ctrl * open_wpa_mon(const char *ifname); +int wait_ip_addr(const char *ifname, int timeout); +int get_wpa_cli_event(struct wpa_ctrl *mon, + const char *event, char *buf, size_t buf_size); +int get_wpa_cli_event2(struct wpa_ctrl *mon, + const char *event, const char *event2, + char *buf, size_t buf_size); + +int add_network(const char *ifname); +int set_network(const char *ifname, int id, const char *field, + const char *value); +int set_network_quoted(const char *ifname, int id, const char *field, + const char *value); +int add_cred(const char *ifname); +int set_cred(const char *ifname, int id, const char *field, const char *value); +int set_cred_quoted(const char *ifname, int id, const char *field, + const char *value); + +#endif /* WPA_HELPERS_H */ diff --git a/lib/nif/wpa_supplicant/wpabuf.h b/lib/nif/wpa_supplicant/wpabuf.h new file mode 100644 index 0000000..eb1db80 --- /dev/null +++ b/lib/nif/wpa_supplicant/wpabuf.h @@ -0,0 +1,191 @@ +/* + * Dynamic data buffer + * Copyright (c) 2007-2012, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef WPABUF_H +#define WPABUF_H + +/* wpabuf::buf is a pointer to external data */ +#define WPABUF_FLAG_EXT_DATA BIT(0) + +/* + * Internal data structure for wpabuf. Please do not touch this directly from + * elsewhere. This is only defined in header file to allow inline functions + * from this file to access data. + */ +struct wpabuf { + size_t size; /* total size of the allocated buffer */ + size_t used; /* length of data in the buffer */ + u8 *buf; /* pointer to the head of the buffer */ + unsigned int flags; + /* optionally followed by the allocated buffer */ +}; + + +int wpabuf_resize(struct wpabuf **buf, size_t add_len); +struct wpabuf * wpabuf_alloc(size_t len); +struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len); +struct wpabuf * wpabuf_alloc_copy(const void *data, size_t len); +struct wpabuf * wpabuf_dup(const struct wpabuf *src); +void wpabuf_free(struct wpabuf *buf); +void wpabuf_clear_free(struct wpabuf *buf); +void * wpabuf_put(struct wpabuf *buf, size_t len); +struct wpabuf * wpabuf_concat(struct wpabuf *a, struct wpabuf *b); +struct wpabuf * wpabuf_zeropad(struct wpabuf *buf, size_t len); +void wpabuf_printf(struct wpabuf *buf, char *fmt, ...) PRINTF_FORMAT(2, 3); +struct wpabuf * wpabuf_parse_bin(const char *buf); + + +/** + * wpabuf_size - Get the currently allocated size of a wpabuf buffer + * @buf: wpabuf buffer + * Returns: Currently allocated size of the buffer + */ +static inline size_t wpabuf_size(const struct wpabuf *buf) +{ + return buf->size; +} + +/** + * wpabuf_len - Get the current length of a wpabuf buffer data + * @buf: wpabuf buffer + * Returns: Currently used length of the buffer + */ +static inline size_t wpabuf_len(const struct wpabuf *buf) +{ + return buf->used; +} + +/** + * wpabuf_tailroom - Get size of available tail room in the end of the buffer + * @buf: wpabuf buffer + * Returns: Tail room (in bytes) of available space in the end of the buffer + */ +static inline size_t wpabuf_tailroom(const struct wpabuf *buf) +{ + return buf->size - buf->used; +} + +/** + * wpabuf_cmp - Check if two buffers contain the same data + * @a: wpabuf buffer + * @b: wpabuf buffer + * Returns: 0 if the two buffers contain the same data and non-zero otherwise + */ +static inline int wpabuf_cmp(const struct wpabuf *a, const struct wpabuf *b) +{ + if (!a && !b) + return 0; + if (a && b && wpabuf_size(a) == wpabuf_size(b)) + return os_memcmp(a->buf, b->buf, wpabuf_size(a)); + return -1; +} + +/** + * wpabuf_head - Get pointer to the head of the buffer data + * @buf: wpabuf buffer + * Returns: Pointer to the head of the buffer data + */ +static inline const void * wpabuf_head(const struct wpabuf *buf) +{ + return buf->buf; +} + +static inline const u8 * wpabuf_head_u8(const struct wpabuf *buf) +{ + return (const u8 *) wpabuf_head(buf); +} + +/** + * wpabuf_mhead - Get modifiable pointer to the head of the buffer data + * @buf: wpabuf buffer + * Returns: Pointer to the head of the buffer data + */ +static inline void * wpabuf_mhead(struct wpabuf *buf) +{ + return buf->buf; +} + +static inline u8 * wpabuf_mhead_u8(struct wpabuf *buf) +{ + return (u8 *) wpabuf_mhead(buf); +} + +static inline void wpabuf_put_u8(struct wpabuf *buf, u8 data) +{ + u8 *pos = (u8 *) wpabuf_put(buf, 1); + *pos = data; +} + +static inline void wpabuf_put_le16(struct wpabuf *buf, u16 data) +{ + u8 *pos = (u8 *) wpabuf_put(buf, 2); + WPA_PUT_LE16(pos, data); +} + +static inline void wpabuf_put_le32(struct wpabuf *buf, u32 data) +{ + u8 *pos = (u8 *) wpabuf_put(buf, 4); + WPA_PUT_LE32(pos, data); +} + +static inline void wpabuf_put_le64(struct wpabuf *buf, u64 data) +{ + u8 *pos = (u8 *) wpabuf_put(buf, 8); + WPA_PUT_LE64(pos, data); +} + +static inline void wpabuf_put_be16(struct wpabuf *buf, u16 data) +{ + u8 *pos = (u8 *) wpabuf_put(buf, 2); + WPA_PUT_BE16(pos, data); +} + +static inline void wpabuf_put_be24(struct wpabuf *buf, u32 data) +{ + u8 *pos = (u8 *) wpabuf_put(buf, 3); + WPA_PUT_BE24(pos, data); +} + +static inline void wpabuf_put_be32(struct wpabuf *buf, u32 data) +{ + u8 *pos = (u8 *) wpabuf_put(buf, 4); + WPA_PUT_BE32(pos, data); +} + +static inline void wpabuf_put_be64(struct wpabuf *buf, u64 data) +{ + u8 *pos = (u8 *) wpabuf_put(buf, 8); + WPA_PUT_BE64(pos, data); +} + +static inline void wpabuf_put_data(struct wpabuf *buf, const void *data, + size_t len) +{ + if (data) + os_memcpy(wpabuf_put(buf, len), data, len); +} + +static inline void wpabuf_put_buf(struct wpabuf *dst, + const struct wpabuf *src) +{ + wpabuf_put_data(dst, wpabuf_head(src), wpabuf_len(src)); +} + +static inline void wpabuf_set(struct wpabuf *buf, const void *data, size_t len) +{ + buf->buf = (u8 *) data; + buf->flags = WPABUF_FLAG_EXT_DATA; + buf->size = buf->used = len; +} + +static inline void wpabuf_put_str(struct wpabuf *dst, const char *str) +{ + wpabuf_put_data(dst, str, os_strlen(str)); +} + +#endif /* WPABUF_H */ diff --git a/src/comm.zig b/src/comm.zig new file mode 100644 index 0000000..70d88b1 --- /dev/null +++ b/src/comm.zig @@ -0,0 +1,198 @@ +///! daemon <-> gui communication +const std = @import("std"); +const json = std.json; +const mem = std.mem; + +pub const Message = union(MessageTag) { + ping: void, + pong: void, + poweroff: void, + wifi_connect: WifiConnect, + network_report: NetworkReport, + get_network_report: GetNetworkReport, + + pub const WifiConnect = struct { + ssid: []const u8, + password: []const u8, + }; + + pub const NetworkReport = struct { + ipaddrs: []const []const u8, + wifi_ssid: ?[]const u8, // null indicates disconnected from wifi + wifi_scan_networks: []const []const u8, + }; + + pub const GetNetworkReport = struct { + scan: bool, // true starts a wifi scan and send NetworkReport only after completion + }; +}; + +pub const MessageTag = enum(u8) { + ping, + pong, + poweroff, + wifi_connect, + network_report, + get_network_report, +}; + +const Header = extern struct { + tag: MessageTag, + len: usize, +}; + +/// reads and parses a single message from the input stream reader. +/// callers must deallocate resources with free when done. +pub fn read(allocator: mem.Allocator, reader: anytype) anyerror!Message { + const h = try reader.readStruct(Header); + if (h.len == 0) { + const m = switch (h.tag) { + .ping => Message{ .ping = {} }, + .pong => Message{ .pong = {} }, + .poweroff => Message{ .poweroff = {} }, + else => error.ZeroLenInNonVoidTag, + }; + return m; + } + + // TODO: limit h.len to some max value + var bytes = try allocator.alloc(u8, h.len); + defer allocator.free(bytes); + try reader.readNoEof(bytes); + + const jopt = json.ParseOptions{ .allocator = allocator, .ignore_unknown_fields = true }; + var jstream = json.TokenStream.init(bytes); + return switch (h.tag) { + .ping, .pong, .poweroff => unreachable, // void + .wifi_connect => Message{ + .wifi_connect = try json.parse(Message.WifiConnect, &jstream, jopt), + }, + .network_report => Message{ + .network_report = try json.parse(Message.NetworkReport, &jstream, jopt), + }, + .get_network_report => Message{ + .get_network_report = try json.parse(Message.GetNetworkReport, &jstream, jopt), + }, + }; +} + +/// outputs the message msg using writer. +/// all allocated resources are freed upon return. +pub fn write(allocator: mem.Allocator, writer: anytype, msg: Message) !void { + var header = Header{ .tag = msg, .len = 0 }; + switch (msg) { + .ping, .pong, .poweroff => return writer.writeStruct(header), + else => {}, // non-zero payload; continue + } + + var data = std.ArrayList(u8).init(allocator); + defer data.deinit(); + const jopt = .{ .whitespace = null }; + switch (msg) { + .ping, .pong, .poweroff => unreachable, + .wifi_connect => try json.stringify(msg.wifi_connect, jopt, data.writer()), + .network_report => try json.stringify(msg.network_report, jopt, data.writer()), + .get_network_report => try json.stringify(msg.get_network_report, jopt, data.writer()), + } + + header.len = data.items.len; + try writer.writeStruct(header); + try writer.writeAll(data.items); +} + +pub fn free(allocator: mem.Allocator, m: Message) void { + switch (m) { + .ping, .pong, .poweroff => {}, + else => |v| { + json.parseFree(@TypeOf(v), v, .{ .allocator = allocator }); + }, + } +} + +test "read" { + const t = std.testing; + + var data = std.ArrayList(u8).init(t.allocator); + defer data.deinit(); + const msg = Message{ .wifi_connect = .{ .ssid = "hello", .password = "world" } }; + try json.stringify(msg.wifi_connect, .{}, data.writer()); + + var buf = std.ArrayList(u8).init(t.allocator); + defer buf.deinit(); + try buf.writer().writeStruct(Header{ .tag = msg, .len = data.items.len }); + try buf.writer().writeAll(data.items); + + var bs = std.io.fixedBufferStream(buf.items); + const res = try read(t.allocator, bs.reader()); + defer free(t.allocator, res); + + try t.expectEqualStrings(msg.wifi_connect.ssid, res.wifi_connect.ssid); + try t.expectEqualStrings(msg.wifi_connect.password, res.wifi_connect.password); +} + +test "write" { + const t = std.testing; + + var buf = std.ArrayList(u8).init(t.allocator); + defer buf.deinit(); + const msg = Message{ .wifi_connect = .{ .ssid = "wlan", .password = "secret" } }; + try write(t.allocator, buf.writer(), msg); + + const payload = "{\"ssid\":\"wlan\",\"password\":\"secret\"}"; + var js = std.ArrayList(u8).init(t.allocator); + defer js.deinit(); + try js.writer().writeStruct(Header{ .tag = msg, .len = payload.len }); + try js.appendSlice(payload); + + try t.expectEqualSlices(u8, js.items, buf.items); +} + +test "write/read void tags" { + const t = std.testing; + + var buf = std.ArrayList(u8).init(t.allocator); + defer buf.deinit(); + + const msg = [_]Message{ + Message.ping, + Message.pong, + Message.poweroff, + }; + + for (msg) |m| { + buf.clearAndFree(); + try write(t.allocator, buf.writer(), m); + var bs = std.io.fixedBufferStream(buf.items); + const res = try read(t.allocator, bs.reader()); + free(t.allocator, res); // noop + try t.expectEqual(m, res); + } +} + +test "msg sequence" { + const t = std.testing; + + var buf = std.ArrayList(u8).init(t.allocator); + defer buf.deinit(); + + const msgs = [_]Message{ + Message.ping, + Message{ .wifi_connect = .{ .ssid = "wlan", .password = "secret" } }, + Message.pong, + Message{ .network_report = .{ + .ipaddrs = &.{}, + .wifi_ssid = null, + .wifi_scan_networks = &.{ "foo", "bar" }, + } }, + }; + for (msgs) |m| { + try write(t.allocator, buf.writer(), m); + } + + var bs = std.io.fixedBufferStream(buf.items); + for (msgs) |m| { + const res = try read(t.allocator, bs.reader()); + defer free(t.allocator, res); + try t.expectEqual(@as(MessageTag, m), @as(MessageTag, res)); + } +} diff --git a/src/main.zig b/src/main.zig deleted file mode 100644 index c2f93f4..0000000 --- a/src/main.zig +++ /dev/null @@ -1,11 +0,0 @@ -const std = @import("std"); - -pub fn main() anyerror!void { - // Note that info level log messages are by default printed only in Debug - // and ReleaseSafe build modes. - std.log.info("All your codebase are belong to us.", .{}); -} - -test "basic test" { - try std.testing.expectEqual(10, 3 + 7); -} diff --git a/src/nd.zig b/src/nd.zig new file mode 100644 index 0000000..76d6c4a --- /dev/null +++ b/src/nd.zig @@ -0,0 +1,225 @@ +const std = @import("std"); +const os = std.os; +const sys = os.system; +const time = std.time; +const Address = std.net.Address; + +const nif = @import("nif"); + +const comm = @import("comm.zig"); +const Daemon = @import("nd/Daemon.zig"); + +const logger = std.log.scoped(.nd); +const stderr = std.io.getStdErr().writer(); + +/// prints usage help text to stderr. +fn usage(prog: []const u8) !void { + try stderr.print( + \\usage: {s} -gui path/to/ngui -gui-user username -wpa path + \\ + \\nd is a short for nakamochi daemon. + \\the daemon executes ngui as a child process and runs until + \\TERM or INT signal is received. + \\ + \\nd logs messages to stderr. + \\ + , .{prog}); +} + +/// prints messages in the same way std.fmt.format does and exits the process +/// with a non-zero code. +fn fatal(comptime fmt: []const u8, args: anytype) noreturn { + stderr.print(fmt, args) catch {}; + if (fmt[fmt.len - 1] != '\n') { + stderr.writeByte('\n') catch {}; + } + std.process.exit(1); +} + +/// nd program args. see usage. +const NdArgs = struct { + gui: ?[:0]const u8 = null, // = "ngui", + gui_user: ?[:0]const u8 = null, // u8 = "uiuser", + wpa: ?[:0]const u8 = null, // = "/var/run/wpa_supplicant/wlan0", + + fn deinit(self: @This(), allocator: std.mem.Allocator) void { + if (self.gui) |p| allocator.free(p); + if (self.gui_user) |p| allocator.free(p); + if (self.wpa) |p| allocator.free(p); + } +}; + +/// parses and validates program args. +fn parseArgs(gpa: std.mem.Allocator) !NdArgs { + var flags: NdArgs = .{}; + + var args = try std.process.ArgIterator.initWithAllocator(gpa); + defer args.deinit(); + const prog = args.next() orelse return error.NoProgName; + + var lastarg: enum { + none, + gui, + gui_user, + wpa, + } = .none; + while (args.next()) |a| { + switch (lastarg) { + .gui => { + flags.gui = try gpa.dupeZ(u8, a); + lastarg = .none; + continue; + }, + .gui_user => { + flags.gui_user = try gpa.dupeZ(u8, a); + lastarg = .none; + continue; + }, + .wpa => { + flags.wpa = try gpa.dupeZ(u8, a); + lastarg = .none; + continue; + }, + .none => {}, + } + if (std.mem.eql(u8, a, "-h") or std.mem.eql(u8, a, "-help") or std.mem.eql(u8, a, "--help")) { + usage(prog) catch {}; + std.process.exit(1); + } else if (std.mem.eql(u8, a, "-gui")) { + lastarg = .gui; + } else if (std.mem.eql(u8, a, "-gui-user")) { + lastarg = .gui_user; + } else if (std.mem.eql(u8, a, "-wpa")) { + lastarg = .wpa; + } else { + fatal("unknown arg name {s}", .{a}); + } + } + + if (lastarg != .none) { + fatal("invalid arg: {s} requires a value", .{@tagName(lastarg)}); + } + if (flags.gui == null) fatal("missing -gui arg", .{}); + if (flags.gui_user == null) fatal("missing -gui-user arg", .{}); + if (flags.wpa == null) fatal("missing -wpa arg", .{}); + + return flags; +} + +/// quit signals nd to exit. +/// TODO: thread-safety? +var quit = false; + +fn sighandler(sig: c_int) callconv(.C) void { + logger.info("got signal {}; exiting...\n", .{sig}); + quit = true; +} + +pub fn main() !void { + // main heap allocator used throughout the lifetime of nd + var gpa_state = std.heap.GeneralPurposeAllocator(.{}){}; + defer if (gpa_state.deinit()) { + logger.err("memory leaks detected", .{}); + }; + const gpa = gpa_state.allocator(); + // parse program args first thing and fail fast if invalid + const args = try parseArgs(gpa); + defer args.deinit(gpa); + + // start ngui, unless -nogui mode + var ngui = std.ChildProcess.init(&.{args.gui.?}, gpa); + ngui.stdin_behavior = .Pipe; + ngui.stdout_behavior = .Pipe; + ngui.stderr_behavior = .Inherit; + // fix zig std: child_process.zig:125:33: error: container 'std.os' has no member called 'getUserInfo' + //ngui.setUserName(args.gui_user) catch |err| { + // fatal("unable to set gui username to {s}: {s}", .{args.gui_user.?, err}); + //}; + // TODO: the following fails with "cannot open framebuffer device: Permission denied" + // but works with "doas -u uiuser ngui" + // ftr, zig uses setreuid and setregid + //const uiuser = std.process.getUserInfo(args.gui_user.?) catch |err| { + // fatal("unable to set gui username to {s}: {any}", .{ args.gui_user.?, err }); + //}; + //ngui.uid = uiuser.uid; + //ngui.gid = uiuser.gid; + // ngui.env_map = ... + ngui.spawn() catch |err| { + fatal("unable to start ngui: {any}", .{err}); + }; + // TODO: thread-safety, esp. uiwriter + const uireader = ngui.stdout.?.reader(); + const uiwriter = ngui.stdin.?.writer(); + + // graceful shutdown; see sigaction(2) + const sa = os.Sigaction{ + .handler = .{ .handler = sighandler }, + .mask = os.empty_sigset, + .flags = 0, + }; + try os.sigaction(os.SIG.INT, &sa, null); + //TODO: try os.sigaction(os.SIG.TERM, &sa, null); + + // start network monitor + var ctrl = try nif.wpa.Control.open(args.wpa.?); + defer ctrl.close() catch {}; + var nd: Daemon = .{ + .allocator = gpa, + .uiwriter = uiwriter, + .wpa_ctrl = ctrl, + }; + try nd.start(); + // send the UI network report right away, without scanning wifi + nd.reportNetworkStatus(.{ .scan = false }); + + // comm with ui loop; run until exit is requested + var poweroff = false; + while (!quit) { + time.sleep(100 * time.ns_per_ms); + // note: uireader.read is blocking + // TODO: handle error.EndOfStream - ngui exited + const msg = comm.read(gpa, uireader) catch |err| { + logger.err("comm.read: {any}", .{err}); + continue; + }; + logger.debug("got ui msg tagged {s}", .{@tagName(msg)}); + switch (msg) { + .pong => {}, + .poweroff => { + logger.info("poweroff requested; terminating", .{}); + quit = true; + poweroff = true; + }, + .get_network_report => |req| { + nd.reportNetworkStatus(.{ .scan = req.scan }); + }, + .wifi_connect => |req| { + nd.startConnectWifi(req.ssid, req.password) catch |err| { + logger.err("startConnectWifi: {any}", .{err}); + }; + }, + else => logger.warn("unhandled msg tag {s}", .{@tagName(msg)}), + } + comm.free(gpa, msg); + } + + // shutdown + _ = ngui.kill() catch |err| logger.err("ngui.kill: {any}", .{err}); + nd.stop(); + if (poweroff) { + svShutdown(gpa); + var off = std.ChildProcess.init(&.{"poweroff"}, gpa); + _ = try off.spawnAndWait(); + } +} + +/// shut down important services manually. +/// TODO: make this OS-agnostic +fn svShutdown(allocator: std.mem.Allocator) void { + // sv waits 7sec by default but bitcoind needs more + // http://smarden.org/runit/ + var stop_lnd = std.ChildProcess.init(&.{"sv", "-w", "25", "stop", "lnd"}, allocator); + _ = stop_lnd.spawnAndWait() catch |err| logger.err("stop lnd: {any}", .{err}); + var stop_btc = std.ChildProcess.init(&.{"sv", "-w", "30", "stop", "bitcoind"}, allocator); + _ = stop_btc.spawnAndWait() catch |err| logger.err("stop bitcoind: {any}", .{err}); +} diff --git a/src/nd/Daemon.zig b/src/nd/Daemon.zig new file mode 100644 index 0000000..0cba88f --- /dev/null +++ b/src/nd/Daemon.zig @@ -0,0 +1,401 @@ +///! daemon watches network status and communicates updates to the gui +///! using uiwriter +const std = @import("std"); +const mem = std.mem; +const time = std.time; + +const nif = @import("nif"); + +const comm = @import("../comm.zig"); +//const ioq = @import("../ioq.zig"); + +const logger = std.log.scoped(.netmon); + +// pub fields +allocator: mem.Allocator, +uiwriter: std.fs.File.Writer, // ngui stdin +wpa_ctrl: nif.wpa.Control, // guarded by mu once start'ed + +// private fields +mu: std.Thread.Mutex = .{}, +quit: bool = false, // tells daemon to quit +main_thread: ?std.Thread = null, // non-nill if started +want_report: bool = false, +want_wifi_scan: bool = false, +wifi_scan_in_progress: bool = false, +report_ready: bool = true, // no need to scan for an immediate report +wpa_save_config_on_connected: bool = false, + +const Daemon = @This(); + +pub fn start(self: *Daemon) !void { + // TODO: return error if already started + self.main_thread = try std.Thread.spawn(.{}, mainThreadLoop, .{self}); +} + +pub fn stop(self: *Daemon) void { + self.mu.lock(); + self.quit = true; + self.mu.unlock(); + if (self.main_thread) |th| { + th.join(); + } +} + +/// main thread entry point. +fn mainThreadLoop(self: *Daemon) !void { + try self.wpa_ctrl.attach(); + defer self.wpa_ctrl.detach() catch |err| logger.err("wpa_ctrl.detach failed on exit: {any}", .{err}); + + while (true) { + time.sleep(1 * time.ns_per_s); + self.mainThreadLoopCycle(); + + self.mu.lock(); + const do_quit = self.quit; + self.mu.unlock(); + if (do_quit) { + break; + } + } +} + +/// run one cycle of the main thread loop iteration. +/// holds self.mu for the whole duration. +fn mainThreadLoopCycle(self: *Daemon) void { + self.mu.lock(); + defer self.mu.unlock(); + self.readWPACtrlMsg() catch |err| logger.err("readWPACtrlMsg: {any}", .{err}); + if (self.want_wifi_scan) { + if (self.startWifiScan()) { + self.want_wifi_scan = false; + } else |err| { + logger.err("startWifiScan: {any}", .{err}); + } + } + if (self.want_report and self.report_ready) { + if (self.sendNetworkReport()) { + self.want_report = false; + } else |err| { + logger.err("sendNetworkReport: {any}", .{err}); + } + } +} + +/// caller must hold self.mu. +fn startWifiScan(self: *Daemon) !void { + try self.wpa_ctrl.scan(); + self.wifi_scan_in_progress = true; + self.report_ready = false; +} + +/// invoked when CTRL-EVENT-SCAN-RESULTS event is seen. +/// caller must hold self.mu. +fn wifiScanComplete(self: *Daemon) void { + self.wifi_scan_in_progress = false; + self.report_ready = true; +} + +/// invoked when CTRL-EVENT-CONNECTED event is seen. +/// caller must hold self.mu. +fn wifiConnected(self: *Daemon) void { + if (self.wpa_save_config_on_connected) { + // fails if update_config=0 in wpa_supplicant.conf + const ok_saved = self.wpa_ctrl.saveConfig(); + if (ok_saved) { + self.wpa_save_config_on_connected = false; + } else |err| { + logger.err("wifiConnected: {any}", .{err}); + } + } + // always send a network report when connected + self.want_report = true; +} + +/// invoked when CTRL-EVENT-SSID-TEMP-DISABLED event with authentication failures is seen. +/// caller must hold self.mu. +fn wifiInvalidKey(self: *Daemon) void { + self.wpa_save_config_on_connected = false; + self.want_report = true; + self.report_ready = true; +} + +pub const ReportNetworkStatusOpt = struct { + scan: bool, +}; + +pub fn reportNetworkStatus(self: *Daemon, opt: ReportNetworkStatusOpt) void { + self.mu.lock(); + defer self.mu.unlock(); + self.want_report = true; + self.want_wifi_scan = opt.scan and !self.wifi_scan_in_progress; + if (self.want_wifi_scan and self.report_ready) { + self.report_ready = false; + } +} + +pub fn startConnectWifi(self: *Daemon, ssid: []const u8, password: []const u8) !void { + if (ssid.len == 0) { + return error.ConnectWifiEmptySSID; + } + const ssid_copy = try self.allocator.dupe(u8, ssid); + const pwd_copy = try self.allocator.dupe(u8, password); + const th = try std.Thread.spawn(.{}, connectWifiThread, .{ self, ssid_copy, pwd_copy }); + th.detach(); +} + +fn connectWifiThread(self: *Daemon, ssid: []const u8, password: []const u8) void { + defer { + self.allocator.free(ssid); + self.allocator.free(password); + } + // https://hostap.epitest.fi/wpa_supplicant/devel/ctrl_iface_page.html + // https://wiki.archlinux.org/title/WPA_supplicant + + // unfortunately, this prevents main thread from looping until released. + // but the following commands and expected to be pretty quick. + self.mu.lock(); + defer self.mu.unlock(); + + const id = self.addWifiNetwork(ssid, password) catch |err| { + logger.err("addWifiNetwork: {any}; exiting", .{err}); + return; + }; + // SELECT_NETWORK - this disables others + // ENABLE_NETWORK + self.wpa_ctrl.selectNetwork(id) catch |err| { + logger.err("selectNetwork({d}): {any}", .{ id, err }); + // non-critical; can try to continue + }; + self.wpa_ctrl.enableNetwork(id) catch |err| { + logger.err("enableNetwork({d}): {any}; cannot continue", .{ id, err }); + self.wpa_ctrl.removeNetwork(id) catch {}; + return; + }; + + // wait for CTRL-EVENT-CONNECTED, SAVE_CONFIG and send network report. + self.wpa_save_config_on_connected = true; +} + +/// adds a new network and configures its parameters. +/// caller must hold self.mu. +fn addWifiNetwork(self: *Daemon, ssid: []const u8, password: []const u8) !u32 { + // - ADD_NETWORK -> get id and set parameters + // - SET_NETWORK ssid "ssid" + // - if password: + // SET_NETWORK psk "password" + // else: + // SET_NETWORK key_mgmt NONE + const newWifiId = try self.wpa_ctrl.addNetwork(); + errdefer self.wpa_ctrl.removeNetwork(newWifiId) catch |err| { + logger.err("addWifiNetwork cleanup: {any}", .{err}); + }; + var buf: [128:0]u8 = undefined; + // TODO: convert ssid to hex string, to support special characters + const ssidZ = try std.fmt.bufPrintZ(&buf, "\"{s}\"", .{ssid}); + try self.wpa_ctrl.setNetworkParam(newWifiId, "ssid", ssidZ); + if (password.len > 0) { + // TODO: switch to wpa_passphrase + const v = try std.fmt.bufPrintZ(&buf, "\"{s}\"", .{password}); + try self.wpa_ctrl.setNetworkParam(newWifiId, "psk", v); + } else { + try self.wpa_ctrl.setNetworkParam(newWifiId, "key_mgmt", "NONE"); + } + + // - LIST_NETWORKS: network id / ssid / bssid / flags + // - for each matching ssid unless it's newly created: REMOVE_NETWORK + if (self.queryWifiNetworksList(.{ .ssid = ssid })) |res| { + defer self.allocator.free(res); + for (res) |id| { + if (id == newWifiId) { + continue; + } + self.wpa_ctrl.removeNetwork(id) catch |err| { + logger.err("wpa_ctrl.removeNetwork({}): {any}", .{ id, err }); + }; + } + } else |err| { + logger.err("queryWifiNetworksList({s}): {any}; won't remove existing, if any", .{ ssid, err }); + } + + return newWifiId; +} + +/// caller must hold self.mu. +fn readWPACtrlMsg(self: *Daemon) !void { + var buf: [512:0]u8 = undefined; + while (try self.wpa_ctrl.pending()) { + const m = try self.wpa_ctrl.receive(&buf); + logger.debug("wpa_ctrl msg: {s}", .{m}); + if (mem.indexOf(u8, m, "CTRL-EVENT-SCAN-RESULTS") != null) { + self.wifiScanComplete(); + } + if (mem.indexOf(u8, m, "CTRL-EVENT-CONNECTED") != null) { + self.wifiConnected(); + } + if (mem.indexOf(u8, m, "CTRL-EVENT-SSID-TEMP-DISABLED") != null) { + // TODO: what about CTRL-EVENT-DISCONNECTED bssid=xx:xx:xx:xx:xx:xx reason=15 + // CTRL-EVENT-SSID-TEMP-DISABLED id=1 ssid="" auth_failures=3 duration=49 reason=WRONG_KEY + var it = mem.tokenize(u8, m, " "); + while (it.next()) |kv_str| { + var kv = mem.split(u8, kv_str, "="); + if (mem.eql(u8, kv.first(), "auth_failures")) { + const v = kv.next(); + if (v != null and !mem.eql(u8, v.?, "0")) { + self.wifiInvalidKey(); + break; + } + } + } + } + // TODO: CTRL-EVENT-DISCONNECTED + } +} + +/// report network status to ngui. +/// caller must hold self.mu. +fn sendNetworkReport(self: *Daemon) !void { + var report = comm.Message.NetworkReport{ + .ipaddrs = undefined, + .wifi_ssid = null, + .wifi_scan_networks = undefined, + }; + + // fetch all public IP addresses using getifaddrs + const pubaddr = try nif.pubAddresses(self.allocator, null); + defer self.allocator.free(pubaddr); + //var addrs = std.ArrayList([]).init(t.allocator); + var ipaddrs = try self.allocator.alloc([]const u8, pubaddr.len); + for (pubaddr) |a, i| { + ipaddrs[i] = try std.fmt.allocPrint(self.allocator, "{s}", .{a}); + } + defer { + for (ipaddrs) |a| self.allocator.free(a); + self.allocator.free(ipaddrs); + } + report.ipaddrs = ipaddrs; + + // get currently connected SSID, if any, from WPA ctrl + const ssid = self.queryWifiSSID() catch |err| blk: { + logger.err("queryWifiSsid: {any}", .{err}); + break :blk null; + }; + defer if (ssid) |v| self.allocator.free(v); + report.wifi_ssid = ssid; + + // fetch available wifi networks from scan results using WPA ctrl + var wifi_networks: ?StringList = if (self.queryWifiScanResults()) |v| v else |err| blk: { + logger.err("queryWifiScanResults: {any}", .{err}); + break :blk null; + }; + defer if (wifi_networks) |*list| list.deinit(); + if (wifi_networks) |list| { + report.wifi_scan_networks = list.items(); + } + + // report everything back to ngui + return comm.write(self.allocator, self.uiwriter, comm.Message{ .network_report = report }); +} + +fn queryWifiSSID(self: *Daemon) !?[]const u8 { + var buf: [512:0]u8 = undefined; + const resp = try self.wpa_ctrl.request("STATUS", &buf, null); + const ssid = "ssid="; + var it = mem.tokenize(u8, resp, "\n"); + while (it.next()) |line| { + if (mem.startsWith(u8, line, ssid)) { + // TODO: check line.len vs ssid.len + const v = try self.allocator.dupe(u8, line[ssid.len..]); + return v; + } + } + return null; +} + +/// callers must free with StringList.deinit. +fn queryWifiScanResults(self: *Daemon) !StringList { + var buf: [8192:0]u8 = undefined; // TODO: what if isn't enough? + // first line is banner: "bssid / frequency / signal level / flags / ssid" + const resp = try self.wpa_ctrl.request("SCAN_RESULTS", &buf, null); + var it = mem.tokenize(u8, resp, "\n"); + if (it.next() == null) { + return error.MissingWifiScanHeader; + } + + var seen = std.BufSet.init(self.allocator); + defer seen.deinit(); + var list = StringList.init(self.allocator); + errdefer list.deinit(); + while (it.next()) |line| { + // TODO: wpactrl's text protocol won't work for names with control characters + if (mem.lastIndexOfScalar(u8, line, '\t')) |i| { + const s = mem.trim(u8, line[i..], "\t\n"); + if (s.len == 0 or seen.contains(s)) { + continue; + } + try seen.insert(s); + try list.append(s); + } + } + return list; +} + +const WifiNetworksListFilter = struct { + ssid: ?[]const u8, // ignore networks whose ssid doesn't match +}; + +/// caller must release results with allocator.free. +fn queryWifiNetworksList(self: *Daemon, filter: WifiNetworksListFilter) ![]u32 { + var buf: [8192:0]u8 = undefined; // TODO: is this enough? + // first line is banner: "network id / ssid / bssid / flags" + const resp = try self.wpa_ctrl.request("LIST_NETWORKS", &buf, null); + var it = mem.tokenize(u8, resp, "\n"); + if (it.next() == null) { + return error.MissingWifiNetworksListHeader; + } + + var list = std.ArrayList(u32).init(self.allocator); + while (it.next()) |line| { + var cols = mem.tokenize(u8, line, "\t"); + const id_str = cols.next() orelse continue; // bad line format? + const ssid = cols.next() orelse continue; // bad line format? + const id = std.fmt.parseUnsigned(u32, id_str, 10) catch continue; // skip bad line + if (filter.ssid != null and !mem.eql(u8, filter.ssid.?, ssid)) { + continue; + } + list.append(id) catch {}; // grab anything we can + } + return list.toOwnedSlice(); +} + +// TODO: turns this into a UniqStringList backed by StringArrayHashMap; also see std.BufSet +const StringList = struct { + l: std.ArrayList([]const u8), + allocator: mem.Allocator, + + const Self = @This(); + + pub fn init(allocator: mem.Allocator) Self { + return Self{ + .l = std.ArrayList([]const u8).init(allocator), + .allocator = allocator, + }; + } + + pub fn deinit(self: *Self) void { + for (self.l.items) |a| { + self.allocator.free(a); + } + self.l.deinit(); + } + + pub fn append(self: *Self, s: []const u8) !void { + const item = try self.allocator.dupe(u8, s); + errdefer self.allocator.free(item); + try self.l.append(item); + } + + pub fn items(self: Self) []const []const u8 { + return self.l.items; + } +}; diff --git a/src/ngui.zig b/src/ngui.zig new file mode 100644 index 0000000..d3711dc --- /dev/null +++ b/src/ngui.zig @@ -0,0 +1,225 @@ +const std = @import("std"); +const mem = std.mem; +const time = std.time; +const Thread = std.Thread; + +const comm = @import("comm.zig"); +const types = @import("types.zig"); +const symbol = @import("ui/symbol.zig"); + +/// SIGPIPE is triggered when a process attempts to write to a broken pipe. +/// by default, SIGPIPE terminates the process without invoking a panic handler. +/// this declaration makes such writes result in EPIPE (error.BrokenPipe) to let +/// the program can handle it. +pub const keep_sigpipe = true; + +const stdin = std.io.getStdIn().reader(); +const stdout = std.io.getStdOut().writer(); +const logger = std.log.scoped(.ngui); +const lvgl_logger = std.log.scoped(.lvgl); // logs LV_LOG_xxx messages + +extern "c" fn lv_timer_handler() u32; +extern "c" fn lv_log_register_print_cb(fn (msg: [*:0]const u8) callconv(.C) void) void; +const LvTimer = opaque {}; +//const LvTimerCallback = *const fn (timer: *LvTimer) callconv(.C) void; // stage2 +const LvTimerCallback = fn (timer: *LvTimer) callconv(.C) void; +extern "c" fn lv_timer_create(callback: LvTimerCallback, period_ms: u32, userdata: ?*anyopaque) *LvTimer; +extern "c" fn lv_timer_del(timer: *LvTimer) void; +extern "c" fn lv_timer_set_repeat_count(timer: *LvTimer, n: i32) void; + +extern "c" fn ui_init() c_int; +extern "c" fn ui_update_network_status(text: [*:0]const u8, wifi_list: ?[*:0]const u8) void; + +/// global heap allocator used throughout the gui program. +/// TODO: thread-safety? +var gpa: mem.Allocator = undefined; + +/// the mutex must be held before any call reaching into lv_xxx functions. +/// all nm_xxx functions assume it is the case since they are invoked from lvgl c code. +var ui_mutex: Thread.Mutex = .{}; +/// the program runs until quit is true. +var quit: bool = false; + +/// a monotonic clock for reporting elapsed ticks to LVGL. +/// the timer runs throughout the whole duration of the UI program. +var tick_timer: types.Timer = undefined; + +/// reports elapsed time in ms since the program start, overflowing at u32 max. +/// it is defined as LVGL custom tick. +export fn nm_get_curr_tick() u32 { + const ms = tick_timer.read() / time.ns_per_ms; + const over = ms >> 32; + if (over > 0) { + return @truncate(u32, over); // LVGL deals with overflow correctly + } + return @truncate(u32, ms); +} + +export fn nm_lvgl_log(msg: [*:0]const u8) void { + const s = mem.span(msg); + lvgl_logger.debug("{s}", .{mem.trimRight(u8, s, "\n")}); +} + +/// initiate system shutdown. +export fn nm_sys_shutdown() void { + logger.info("initiating system shutdown", .{}); + const msg = comm.Message.poweroff; + comm.write(gpa, stdout, msg) catch |err| logger.err("nm_sys_shutdown: {any}", .{err}); + quit = true; +} + +export fn nm_tab_settings_active() void { + logger.info("starting wifi scan", .{}); + const msg = comm.Message{ .get_network_report = .{ .scan = true } }; + comm.write(gpa, stdout, msg) catch |err| logger.err("nm_tab_settings_active: {any}", .{err}); +} + +export fn nm_request_network_status(t: *LvTimer) void { + lv_timer_del(t); + const msg: comm.Message = .{ .get_network_report = .{ .scan = false } }; + comm.write(gpa, stdout, msg) catch |err| logger.err("nm_request_network_status: {any}", .{err}); +} + +/// ssid and password args must not outlive this function. +export fn nm_wifi_start_connect(ssid: [*:0]const u8, password: [*:0]const u8) void { + const msg = comm.Message{ .wifi_connect = .{ + .ssid = mem.span(ssid), + .password = mem.span(password), + } }; + logger.info("connect to wifi [{s}]", .{msg.wifi_connect.ssid}); + comm.write(gpa, stdout, msg) catch |err| { + logger.err("comm.write: {any}", .{err}); + }; +} + +fn updateNetworkStatus(report: comm.Message.NetworkReport) !void { + ui_mutex.lock(); + defer ui_mutex.unlock(); + + var wifi_list: ?[:0]const u8 = null; + var wifi_list_ptr: ?[*:0]const u8 = null; + if (report.wifi_scan_networks.len > 0) { + wifi_list = try mem.joinZ(gpa, "\n", report.wifi_scan_networks); + wifi_list_ptr = wifi_list.?.ptr; + } + defer if (wifi_list) |v| gpa.free(v); + + var status = std.ArrayList(u8).init(gpa); // free'd as owned slice below + const w = status.writer(); + if (report.wifi_ssid) |ssid| { + try w.writeAll(symbol.Ok); + try w.print(" connected to {s}", .{ssid}); + } else { + try w.writeAll(symbol.Warning); + try w.print(" disconnected", .{}); + } + + if (report.ipaddrs.len > 0) { + const ipaddrs = try mem.join(gpa, "\n", report.ipaddrs); + defer gpa.free(ipaddrs); + try w.print("\n\nIP addresses:\n{s}", .{ipaddrs}); + } + + const text = try status.toOwnedSliceSentinel(0); + defer gpa.free(text); + ui_update_network_status(text, wifi_list_ptr); + + // request network status again if we're connected but IP addr list is empty. + // can happen with a fresh connection while dhcp is still in progress. + if (report.wifi_ssid != null and report.ipaddrs.len == 0) { + // TODO: sometimes this is too fast, not all ip addrs are avail (ipv4 vs ipv6) + var t = lv_timer_create(nm_request_network_status, 1000, null); + lv_timer_set_repeat_count(t, 1); + } +} + +/// reads messages from nd; loops indefinitely until program exit +fn commThread() void { + while (true) { + commThreadLoopCycle() catch |err| logger.err("commThreadLoopCycle: {any}", .{err}); + ui_mutex.lock(); + const do_quit = quit; + ui_mutex.unlock(); + if (do_quit) { + return; + } + } +} + +fn commThreadLoopCycle() !void { + const msg = comm.read(gpa, stdin) catch |err| { + if (err == error.EndOfStream) { + // pointless to continue running if comms is broken + ui_mutex.lock(); + quit = true; + ui_mutex.unlock(); + } + return err; + }; + defer comm.free(gpa, msg); + logger.debug("got msg tagged {s}", .{@tagName(msg)}); + switch (msg) { + .ping => try comm.write(gpa, stdout, comm.Message.pong), + .network_report => |report| { + updateNetworkStatus(report) catch |err| logger.err("updateNetworkStatus: {any}", .{err}); + }, + else => logger.warn("unhandled msg tag {s}", .{@tagName(msg)}), + } +} + +/// nakamochi UI program entry point. +pub fn main() anyerror!void { + // ensure timer is available on this platform before doing anything else; + // the UI is unusable otherwise. + tick_timer = try time.Timer.start(); + + // main heap allocator used through the lifetime of nd + var gpa_state = std.heap.GeneralPurposeAllocator(.{}){}; + defer if (gpa_state.deinit()) { + logger.err("memory leaks detected", .{}); + }; + gpa = gpa_state.allocator(); + + // info level log messages are by default printed only in Debug and ReleaseSafe build modes. + lv_log_register_print_cb(nm_lvgl_log); + + const c_res = ui_init(); + if (c_res != 0) { + logger.err("ui_init failed with code {}", .{c_res}); + std.process.exit(1); + } + const th = try Thread.spawn(.{}, commThread, .{}); + th.detach(); + + // TODO: handle sigterm + while (true) { + ui_mutex.lock(); + var till_next_ms = lv_timer_handler(); + const do_quit = quit; + ui_mutex.unlock(); + if (do_quit) { + return; + } + // sleep at least 1ms + time.sleep(@maximum(1, till_next_ms) * time.ns_per_ms); + } +} + +test "tick" { + const t = std.testing; + + tick_timer = types.Timer{ .value = 0 }; + try t.expectEqual(@as(u32, 0), nm_get_curr_tick()); + + tick_timer.value = 1 * time.ns_per_ms; + try t.expectEqual(@as(u32, 1), nm_get_curr_tick()); + + tick_timer.value = 13 * time.ns_per_ms; + try t.expectEqual(@as(u32, 13), nm_get_curr_tick()); + + tick_timer.value = @as(u64, ~@as(u32, 0)) * time.ns_per_ms; + try t.expectEqual(@as(u32, std.math.maxInt(u32)), nm_get_curr_tick()); + + tick_timer.value = (1 << 32) * time.ns_per_ms; + try t.expectEqual(@as(u32, 1), nm_get_curr_tick()); +} diff --git a/src/test.zig b/src/test.zig new file mode 100644 index 0000000..6e173f4 --- /dev/null +++ b/src/test.zig @@ -0,0 +1,16 @@ +const std = @import("std"); + +export fn wifi_ssid_add_network(name: [*:0]const u8) void { + _ = name; +} + +export fn lv_timer_del(timer: *opaque{}) void { + _ = timer; +} + +test { + std.testing.refAllDecls(@This()); + + _ = @import("comm.zig"); + _ = @import("ngui.zig"); +} diff --git a/src/types.zig b/src/types.zig new file mode 100644 index 0000000..76d1e6f --- /dev/null +++ b/src/types.zig @@ -0,0 +1,14 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +pub const Timer = if (builtin.is_test) TestTimer else std.time.Timer; + +/// TestTimer always reports the same fixed value. +pub const TestTimer = if (!builtin.is_test) @compileError("TestTimer is for tests only") else struct { + value: u64, + + pub fn read(self: *Timer) u64 { + return self.value; + } +}; + diff --git a/src/ui/c/drv_fbev.c b/src/ui/c/drv_fbev.c new file mode 100644 index 0000000..840195e --- /dev/null +++ b/src/ui/c/drv_fbev.c @@ -0,0 +1,56 @@ +/** + * framebuffer display + evdev touchpad drivers init + */ + +#include "lvgl/lvgl.h" +#include "lv_drivers/display/fbdev.h" +#include "lv_drivers/indev/evdev.h" + +#define DISP_BUF_SIZE NM_DISP_HOR * NM_DISP_VER / 10 + +lv_disp_t* drv_init(void) +{ + fbdev_init(); + + static lv_disp_draw_buf_t buf; + static lv_color_t cb[DISP_BUF_SIZE]; + lv_disp_draw_buf_init(&buf, cb, NULL, DISP_BUF_SIZE); + uint32_t hor, vert; + fbdev_get_sizes(&hor, &vert, NULL); + if (hor != NM_DISP_HOR || vert != NM_DISP_VER) { + LV_LOG_WARN("framebuffer display mismatch; expected %dx%d", NM_DISP_HOR, NM_DISP_VER); + } + + static lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); + disp_drv.draw_buf = &buf; + disp_drv.hor_res = NM_DISP_HOR; + disp_drv.ver_res = NM_DISP_VER; + disp_drv.antialiasing = 1; + disp_drv.flush_cb = fbdev_flush; + lv_disp_t* disp = lv_disp_drv_register(&disp_drv); + if (disp == NULL) { + return NULL; + } + + /* keypad input devices default group; + * future-proof: don't have any atm */ + lv_group_t* g = lv_group_create(); + if (g == NULL) { + return NULL; + } + lv_group_set_default(g); + + evdev_init(); + static lv_indev_drv_t touchpad_drv; + lv_indev_drv_init(&touchpad_drv); + touchpad_drv.type = LV_INDEV_TYPE_POINTER; + touchpad_drv.read_cb = evdev_read; + lv_indev_t* touchpad = lv_indev_drv_register(&touchpad_drv); + if (touchpad == NULL) { + /* TODO: or continue without the touchpad? */ + return NULL; + } + + return disp; +} diff --git a/src/ui/c/drv_sdl2.c b/src/ui/c/drv_sdl2.c new file mode 100644 index 0000000..f59bbfe --- /dev/null +++ b/src/ui/c/drv_sdl2.c @@ -0,0 +1,73 @@ +/** + * SDL2 drivers init for display, keyboard and mouse + */ + +#include "lvgl/lvgl.h" +#include "lvgl/src/misc/lv_log.h" +#include "lv_drivers/sdl/sdl.h" + +#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/ +#include SDL_INCLUDE_PATH + +lv_disp_t* drv_init(void) +{ + sdl_init(); + SDL_DisplayMode dm; + int dm_err = SDL_GetDesktopDisplayMode(0, &dm); + if (dm_err != 0) { + LV_LOG_WARN("SDL_GetDesktopDisplayMode: %i", dm_err); + } else { + unsigned char bpp = SDL_BITSPERPIXEL(dm.format); + LV_LOG_INFO("%ix%i %dbpp %s", dm.w, dm.h, bpp, SDL_GetPixelFormatName(dm.format)); + if (dm.w != NM_DISP_HOR || dm.h != NM_DISP_VER || bpp != LV_COLOR_DEPTH) { + LV_LOG_WARN("SDL display mismatch; expected %dx%d %dbpp", NM_DISP_HOR, NM_DISP_VER, LV_COLOR_DEPTH); + } + } + + static lv_disp_draw_buf_t buf; + static lv_color_t cb1[NM_DISP_HOR * 100]; + static lv_color_t cb2[NM_DISP_HOR * 100]; + lv_disp_draw_buf_init(&buf, cb1, cb2, NM_DISP_HOR * 100); + + static lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); + disp_drv.draw_buf = &buf; + disp_drv.flush_cb = sdl_display_flush; + disp_drv.hor_res = NM_DISP_HOR; + disp_drv.ver_res = NM_DISP_VER; + disp_drv.antialiasing = 1; + lv_disp_t* disp = lv_disp_drv_register(&disp_drv); + if (disp == NULL) { + return NULL; + } + + static lv_indev_drv_t mouse_drv; + lv_indev_drv_init(&mouse_drv); + mouse_drv.type = LV_INDEV_TYPE_POINTER; + mouse_drv.read_cb = sdl_mouse_read; + lv_indev_t* mouse = lv_indev_drv_register(&mouse_drv); + if (mouse == NULL) { + LV_LOG_WARN("lv_indev_drv_register(&mouse_drv) returned NULL"); + } + + /* keypad input devices default group */ + lv_group_t * g = lv_group_create(); + if (g == NULL) { + LV_LOG_WARN("lv_group_create returned NULL; won't set default group"); + } else { + lv_group_set_default(g); + } + + static lv_indev_drv_t keyboard_drv; + lv_indev_drv_init(&keyboard_drv); + keyboard_drv.type = LV_INDEV_TYPE_KEYPAD; + keyboard_drv.read_cb = sdl_keyboard_read; + lv_indev_t *kb = lv_indev_drv_register(&keyboard_drv); + if (kb == NULL) { + LV_LOG_WARN("lv_indev_drv_register(&keyboard_drv) returned NULL"); + } else if (g) { + lv_indev_set_group(kb, g); + } + + return disp; +} diff --git a/src/ui/c/lv_conf.h b/src/ui/c/lv_conf.h new file mode 100644 index 0000000..e23aa20 --- /dev/null +++ b/src/ui/c/lv_conf.h @@ -0,0 +1,718 @@ +/** + * LVGL config file for v8.3.1 + * see lib/lvgl/lv_conf_template.h for initial values + */ + +#ifndef LV_CONF_H +#define LV_CONF_H + +#include + +/*==================== + COLOR SETTINGS + *====================*/ + +/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/ +#define LV_COLOR_DEPTH 16 + +/*Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI)*/ +#define LV_COLOR_16_SWAP 0 + +/*Enable features to draw on transparent background. + *It's required if opa, and transform_* style properties are used. + *Can be also used if the UI is above another layer, e.g. an OSD menu or video player.*/ +#define LV_COLOR_SCREEN_TRANSP 0 + +/* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently. + * 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */ +#define LV_COLOR_MIX_ROUND_OFS 0 + +/*Images pixels with this color will not be drawn if they are chroma keyed)*/ +#define LV_COLOR_CHROMA_KEY lv_color_hex(0x00ff00) /*pure green*/ + +/*========================= + MEMORY SETTINGS + *=========================*/ + +/*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/ +// TODO: research benefits of lv_mem_alloc +#define LV_MEM_CUSTOM 1 +#define LV_MEM_CUSTOM_INCLUDE +#define LV_MEM_CUSTOM_ALLOC malloc +#define LV_MEM_CUSTOM_FREE free +#define LV_MEM_CUSTOM_REALLOC realloc + +/*Number of the intermediate memory buffer used during rendering and other internal processing mechanisms. + *You will see an error log message if there wasn't enough buffers. */ +#define LV_MEM_BUF_MAX_NUM 16 + +/*Use the standard `memcpy` and `memset` instead of LVGL's own functions. (Might or might not be faster).*/ +#define LV_MEMCPY_MEMSET_STD 0 + +/*==================== + HAL SETTINGS + *====================*/ + +/*Default display refresh period. LVG will redraw changed areas with this period time*/ +#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/ + +/*Input device read period in milliseconds*/ +#define LV_INDEV_DEF_READ_PERIOD 30 /*[ms]*/ + +/*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings. + *(Not so important, you can adjust it to modify default sizes and spaces)*/ +#define LV_DPI_DEF 130 /*[px/inch]*/ + +/*======================= + * FEATURE CONFIGURATION + *=======================*/ + +/*------------- + * Drawing + *-----------*/ + +/*Enable complex draw engine. + *Required to draw shadow, gradient, rounded corners, circles, arc, skew lines, image transformations or any masks*/ +#define LV_DRAW_COMPLEX 1 + +/*Allow buffering some shadow calculation. +*LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius` +*Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost*/ +#define LV_SHADOW_CACHE_SIZE 0 + +/* Set number of maximally cached circle data. +* The circumference of 1/4 circle are saved for anti-aliasing +* radius * 4 bytes are used per circle (the most often used radiuses are saved) +* 0: to disable caching */ +#define LV_CIRCLE_CACHE_SIZE 4 + +/** + * "Simple layers" are used when a widget has `style_opa < 255` to buffer the widget into a layer + * and blend it as an image with the given opacity. + * Note that `bg_opa`, `text_opa` etc don't require buffering into layer) + * The widget can be buffered in smaller chunks to avoid using large buffers. + * + * - LV_LAYER_SIMPLE_BUF_SIZE: [bytes] the optimal target buffer size. LVGL will try to allocate it + * - LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE: [bytes] used if `LV_LAYER_SIMPLE_BUF_SIZE` couldn't be allocated. + * + * Both buffer sizes are in bytes. + * "Transformed layers" (where transform_angle/zoom properties are used) use larger buffers + * and can't be drawn in chunks. So these settings affects only widgets with opacity. + */ +#define LV_LAYER_SIMPLE_BUF_SIZE (24 * 1024) +#define LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE (3 * 1024) + +/*Default image cache size. Image caching keeps the images opened. + *If only the built-in image formats are used there is no real advantage of caching. (I.e. if no new image decoder is added) + *With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images. + *However the opened images might consume additional RAM. + *0: to disable caching*/ +#define LV_IMG_CACHE_DEF_SIZE 0 + +/*Number of stops allowed per gradient. Increase this to allow more stops. + *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/ +#define LV_GRADIENT_MAX_STOPS 2 + +/*Default gradient buffer size. + *When LVGL calculates the gradient "maps" it can save them into a cache to avoid calculating them again. + *LV_GRAD_CACHE_DEF_SIZE sets the size of this cache in bytes. + *If the cache is too small the map will be allocated only while it's required for the drawing. + *0 mean no caching.*/ +#define LV_GRAD_CACHE_DEF_SIZE 0 + +/*Allow dithering the gradients (to achieve visual smooth color gradients on limited color depth display) + *LV_DITHER_GRADIENT implies allocating one or two more lines of the object's rendering surface + *The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion */ +#define LV_DITHER_GRADIENT 0 + +/*Maximum buffer size to allocate for rotation. + *Only used if software rotation is enabled in the display driver.*/ +#define LV_DISP_ROT_MAX_BUF (10*1024) + +/*------------- + * GPU + *-----------*/ + +/*Use Arm's 2D acceleration library Arm-2D */ +/* TODO: consider enabling for rpi? */ +#define LV_USE_GPU_ARM2D 0 + +/*Use STM32's DMA2D (aka Chrom Art) GPU*/ +#define LV_USE_GPU_STM32_DMA2D 0 +#if LV_USE_GPU_STM32_DMA2D + /*Must be defined to include path of CMSIS header of target processor + e.g. "stm32f769xx.h" or "stm32f429xx.h"*/ + #define LV_GPU_DMA2D_CMSIS_INCLUDE +#endif + +/*Use SWM341's DMA2D GPU*/ +#define LV_USE_GPU_SWM341_DMA2D 0 +#if LV_USE_GPU_SWM341_DMA2D + #define LV_GPU_SWM341_DMA2D_INCLUDE "SWM341.h" +#endif + +/*Use NXP's PXP GPU iMX RTxxx platforms*/ +#define LV_USE_GPU_NXP_PXP 0 +#if LV_USE_GPU_NXP_PXP + /*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c) + * and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol SDK_OS_FREE_RTOS + * has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected. + *0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init() + */ + #define LV_USE_GPU_NXP_PXP_AUTO_INIT 0 +#endif + +/*Use NXP's VG-Lite GPU iMX RTxxx platforms*/ +#define LV_USE_GPU_NXP_VG_LITE 0 + +/*Use SDL renderer API*/ +#define LV_USE_GPU_SDL 0 +#if LV_USE_GPU_SDL + #define LV_GPU_SDL_INCLUDE_PATH + /*Texture cache size, 8MB by default*/ + #define LV_GPU_SDL_LRU_SIZE (1024 * 1024 * 8) + /*Custom blend mode for mask drawing, disable if you need to link with older SDL2 lib*/ + #define LV_GPU_SDL_CUSTOM_BLEND_MODE (SDL_VERSION_ATLEAST(2, 0, 6)) +#endif + +/*------------- + * Logging + *-----------*/ + +/*Enable the log module*/ +#define LV_USE_LOG 1 +#if LV_USE_LOG + + /*How important log should be added: + *LV_LOG_LEVEL_TRACE A lot of logs to give detailed information + *LV_LOG_LEVEL_INFO Log important events + *LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem + *LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail + *LV_LOG_LEVEL_USER Only logs added by the user + *LV_LOG_LEVEL_NONE Do not log anything*/ + #define LV_LOG_LEVEL LV_LOG_LEVEL_INFO + + /*1: Print the log with 'printf'; + *0: User need to register a callback with `lv_log_register_print_cb()`*/ + #define LV_LOG_PRINTF 0 + + /*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/ + #define LV_LOG_TRACE_MEM 0 + #define LV_LOG_TRACE_TIMER 0 + #define LV_LOG_TRACE_INDEV 1 + #define LV_LOG_TRACE_DISP_REFR 1 + #define LV_LOG_TRACE_EVENT 1 + #define LV_LOG_TRACE_OBJ_CREATE 0 + #define LV_LOG_TRACE_LAYOUT 0 + #define LV_LOG_TRACE_ANIM 0 + +#endif /*LV_USE_LOG*/ + +/*------------- + * Asserts + *-----------*/ + +/*Enable asserts if an operation is failed or an invalid data is found. + *If LV_USE_LOG is enabled an error message will be printed on failure*/ +#define LV_USE_ASSERT_NULL 1 /*Check if the parameter is NULL. (Very fast, recommended)*/ +#define LV_USE_ASSERT_MALLOC 1 /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/ +#define LV_USE_ASSERT_STYLE 0 /*Check if the styles are properly initialized. (Very fast, recommended)*/ +#define LV_USE_ASSERT_MEM_INTEGRITY 0 /*Check the integrity of `lv_mem` after critical operations. (Slow)*/ +#define LV_USE_ASSERT_OBJ 0 /*Check the object's type and existence (e.g. not deleted). (Slow)*/ + +/*Add a custom handler when assert happens e.g. to restart the MCU*/ +#define LV_ASSERT_HANDLER_INCLUDE +#define LV_ASSERT_HANDLER while(1); /*Halt by default*/ + +/*------------- + * Others + *-----------*/ + +/*1: Show CPU usage and FPS count*/ +#define LV_USE_PERF_MONITOR 0 +#if LV_USE_PERF_MONITOR + #define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT +#endif + +/*1: Show the used memory and the memory fragmentation + * Requires LV_MEM_CUSTOM = 0*/ +#define LV_USE_MEM_MONITOR 0 +#if LV_USE_MEM_MONITOR + #define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT +#endif + +/*1: Draw random colored rectangles over the redrawn areas*/ +#define LV_USE_REFR_DEBUG 0 + +/*Change the built in (v)snprintf functions*/ +#define LV_SPRINTF_CUSTOM 0 +#if LV_SPRINTF_CUSTOM + #define LV_SPRINTF_INCLUDE + #define lv_snprintf snprintf + #define lv_vsnprintf vsnprintf +#else /*LV_SPRINTF_CUSTOM*/ + #define LV_SPRINTF_USE_FLOAT 0 +#endif /*LV_SPRINTF_CUSTOM*/ + +#define LV_USE_USER_DATA 1 + +/*Garbage Collector settings + *Used if lvgl is bound to higher level language and the memory is managed by that language*/ +#define LV_ENABLE_GC 0 +#if LV_ENABLE_GC != 0 + #define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/ +#endif /*LV_ENABLE_GC*/ + +/*===================== + * COMPILER SETTINGS + *====================*/ + +/*For big endian systems set to 1*/ +#define LV_BIG_ENDIAN_SYSTEM 0 + +/*Define a custom attribute to `lv_tick_inc` function*/ +#define LV_ATTRIBUTE_TICK_INC + +/*Define a custom attribute to `lv_timer_handler` function*/ +#define LV_ATTRIBUTE_TIMER_HANDLER + +/*Define a custom attribute to `lv_disp_flush_ready` function*/ +#define LV_ATTRIBUTE_FLUSH_READY + +/*Required alignment size for buffers*/ +#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1 + +/*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default). + * E.g. __attribute__((aligned(4)))*/ +#define LV_ATTRIBUTE_MEM_ALIGN + +/*Attribute to mark large constant arrays for example font's bitmaps*/ +#define LV_ATTRIBUTE_LARGE_CONST + +/*Compiler prefix for a big array declaration in RAM*/ +#define LV_ATTRIBUTE_LARGE_RAM_ARRAY + +/*Place performance critical functions into a faster memory (e.g RAM)*/ +#define LV_ATTRIBUTE_FAST_MEM + +/*Prefix variables that are used in GPU accelerated operations, often these need to be placed in RAM sections that are DMA accessible*/ +#define LV_ATTRIBUTE_DMA + +/*Export integer constant to binding. This macro is used with constants in the form of LV_ that + *should also appear on LVGL binding API such as Micropython.*/ +#define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/ + +/*Extend the default -32k..32k coordinate range to -4M..4M by using int32_t for coordinates instead of int16_t*/ +#define LV_USE_LARGE_COORD 0 + +/*================== + * FONT USAGE + *===================*/ + +/*Montserrat fonts with ASCII range and some symbols using bpp = 4 + *https://fonts.google.com/specimen/Montserrat*/ +#define LV_FONT_MONTSERRAT_8 0 +#define LV_FONT_MONTSERRAT_10 0 +#define LV_FONT_MONTSERRAT_12 0 +#define LV_FONT_MONTSERRAT_14 0 +#define LV_FONT_MONTSERRAT_16 0 +#define LV_FONT_MONTSERRAT_18 0 +#define LV_FONT_MONTSERRAT_20 0 +#define LV_FONT_MONTSERRAT_22 0 +#define LV_FONT_MONTSERRAT_24 0 +#define LV_FONT_MONTSERRAT_26 0 +#define LV_FONT_MONTSERRAT_28 0 +#define LV_FONT_MONTSERRAT_30 0 +#define LV_FONT_MONTSERRAT_32 0 +#define LV_FONT_MONTSERRAT_34 0 +#define LV_FONT_MONTSERRAT_36 0 +#define LV_FONT_MONTSERRAT_38 0 +#define LV_FONT_MONTSERRAT_40 0 +#define LV_FONT_MONTSERRAT_42 0 +#define LV_FONT_MONTSERRAT_44 0 +#define LV_FONT_MONTSERRAT_46 0 +#define LV_FONT_MONTSERRAT_48 0 + +/*Demonstrate special features*/ +#define LV_FONT_MONTSERRAT_12_SUBPX 0 +#define LV_FONT_MONTSERRAT_28_COMPRESSED 0 /*bpp = 3*/ +#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0 /*Hebrew, Arabic, Persian letters and all their forms*/ +#define LV_FONT_SIMSUN_16_CJK 0 /*1000 most common CJK radicals*/ + +/*Pixel perfect monospace fonts*/ +#define LV_FONT_UNSCII_8 0 +#define LV_FONT_UNSCII_16 0 + +/*Optionally declare custom fonts here. + *You can use these fonts as default font too and they will be available globally. + *E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/ +#define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(lv_font_courierprimecode_14) LV_FONT_DECLARE(lv_font_courierprimecode_24) + +/*Always set a default font*/ +//#define LV_FONT_DEFAULT &lv_font_montserrat_14 +#define LV_FONT_DEFAULT &lv_font_courierprimecode_14 + +/* additional fontawesome symbols to complement LV_SYMBOL_xxx */ +#define NM_SYMBOL_BITCOIN "\xEF\x8D\xB9" /* 0xF379 */ +#define NM_SYMBOL_BITCOIN_SIGN "\xEE\x82\xB4" /* 0xE0B4 */ +#define NM_SYMBOL_BOLT "\xEF\x83\xA7" /* 0xF0E7 */ + +/*Enable handling large font and/or fonts with a lot of characters. + *The limit depends on the font size, font face and bpp. + *Compiler error will be triggered if a font needs it.*/ +#define LV_FONT_FMT_TXT_LARGE 0 + +/*Enables/disables support for compressed fonts.*/ +#define LV_USE_FONT_COMPRESSED 0 + +/*Enable subpixel rendering*/ +#define LV_USE_FONT_SUBPX 0 +#if LV_USE_FONT_SUBPX + /*Set the pixel order of the display. Physical order of RGB channels. Doesn't matter with "normal" fonts.*/ + #define LV_FONT_SUBPX_BGR 0 /*0: RGB; 1:BGR order*/ +#endif + +/*Enable drawing placeholders when glyph dsc is not found*/ +#define LV_USE_FONT_PLACEHOLDER 1 + +/*================= + * TEXT SETTINGS + *=================*/ + +/** + * Select a character encoding for strings. + * Your IDE or editor should have the same character encoding + * - LV_TXT_ENC_UTF8 + * - LV_TXT_ENC_ASCII + */ +#define LV_TXT_ENC LV_TXT_ENC_UTF8 + +/*Can break (wrap) texts on these chars*/ +#define LV_TXT_BREAK_CHARS " ,.;:-_" + +/*If a word is at least this long, will break wherever "prettiest" + *To disable, set to a value <= 0*/ +#define LV_TXT_LINE_BREAK_LONG_LEN 0 + +/*Minimum number of characters in a long word to put on a line before a break. + *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ +#define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3 + +/*Minimum number of characters in a long word to put on a line after a break. + *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/ +#define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3 + +/*The control character to use for signalling text recoloring.*/ +#define LV_TXT_COLOR_CMD "#" + +/*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts. + *The direction will be processed according to the Unicode Bidirectional Algorithm: + *https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/ +#define LV_USE_BIDI 1 +#if LV_USE_BIDI + /*Set the default direction. Supported values: + *`LV_BASE_DIR_LTR` Left-to-Right + *`LV_BASE_DIR_RTL` Right-to-Left + *`LV_BASE_DIR_AUTO` detect texts base direction*/ + #define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO +#endif + +/*Enable Arabic/Persian processing + *In these languages characters should be replaced with an other form based on their position in the text*/ +#define LV_USE_ARABIC_PERSIAN_CHARS 0 + +/*================== + * WIDGET USAGE + *================*/ + +/*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/ + +#define LV_USE_ARC 1 + +#define LV_USE_BAR 1 + +#define LV_USE_BTN 1 + +#define LV_USE_BTNMATRIX 1 + +#define LV_USE_CANVAS 1 + +#define LV_USE_CHECKBOX 1 + +#define LV_USE_DROPDOWN 1 /*Requires: lv_label*/ + +#define LV_USE_IMG 1 /*Requires: lv_label*/ + +#define LV_USE_LABEL 1 +#if LV_USE_LABEL + #define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/ + #define LV_LABEL_LONG_TXT_HINT 1 /*Store some extra info in labels to speed up drawing of very long texts*/ +#endif + +#define LV_USE_LINE 1 + +#define LV_USE_ROLLER 1 /*Requires: lv_label*/ +#if LV_USE_ROLLER + #define LV_ROLLER_INF_PAGES 7 /*Number of extra "pages" when the roller is infinite*/ +#endif + +#define LV_USE_SLIDER 1 /*Requires: lv_bar*/ + +#define LV_USE_SWITCH 1 + +#define LV_USE_TEXTAREA 1 /*Requires: lv_label*/ +#define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500 /*ms*/ + +#define LV_USE_TABLE 1 + +/*================== + * EXTRA COMPONENTS + *==================*/ + +/*----------- + * Widgets + *----------*/ +#define LV_USE_ANIMIMG 1 + +#define LV_USE_CALENDAR 1 +#define LV_CALENDAR_WEEK_STARTS_MONDAY 1 +#if LV_CALENDAR_WEEK_STARTS_MONDAY + #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"} +#else + #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"} +#endif + +#define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} +#define LV_USE_CALENDAR_HEADER_ARROW 1 +#define LV_USE_CALENDAR_HEADER_DROPDOWN 1 + +#define LV_USE_CHART 1 + +#define LV_USE_COLORWHEEL 1 + +#define LV_USE_IMGBTN 1 + +#define LV_USE_KEYBOARD 1 + +#define LV_USE_LED 1 + +#define LV_USE_LIST 1 + +#define LV_USE_MENU 1 + +#define LV_USE_METER 1 + +#define LV_USE_MSGBOX 1 + +#define LV_USE_SPAN 1 +/*A line text can contain maximum num of span descriptor */ +#define LV_SPAN_SNIPPET_STACK_SIZE 64 + +#define LV_USE_SPINBOX 1 + +#define LV_USE_SPINNER 1 + +#define LV_USE_TABVIEW 1 + +#define LV_USE_TILEVIEW 1 + +#define LV_USE_WIN 1 + +/*----------- + * Themes + *----------*/ + +/*A simple, impressive and very complete theme*/ +#define LV_USE_THEME_DEFAULT 1 +#if LV_USE_THEME_DEFAULT + + /*0: Light mode; 1: Dark mode*/ + #define LV_THEME_DEFAULT_DARK 0 + + /*1: Enable grow on press*/ + #define LV_THEME_DEFAULT_GROW 1 + + /*Default transition time in [ms]*/ + #define LV_THEME_DEFAULT_TRANSITION_TIME 80 +#endif /*LV_USE_THEME_DEFAULT*/ + +/*A very simple theme that is a good starting point for a custom theme*/ +#define LV_USE_THEME_BASIC 1 + +/*A theme designed for monochrome displays*/ +#define LV_USE_THEME_MONO 1 + +/*----------- + * Layouts + *----------*/ + +/*A layout similar to Flexbox in CSS.*/ +#define LV_USE_FLEX 1 + +/*A layout similar to Grid in CSS.*/ +#define LV_USE_GRID 1 + +/*--------------------- + * 3rd party libraries + *--------------------*/ + +/*File system interfaces for common APIs */ + +/*API for fopen, fread, etc*/ +#define LV_USE_FS_STDIO 0 +#if LV_USE_FS_STDIO + #define LV_FS_STDIO_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_STDIO_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ + #define LV_FS_STDIO_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ +#endif + +/*API for open, read, etc*/ +#define LV_USE_FS_POSIX 0 +#if LV_USE_FS_POSIX + #define LV_FS_POSIX_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_POSIX_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ + #define LV_FS_POSIX_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ +#endif + +/*API for CreateFile, ReadFile, etc*/ +#define LV_USE_FS_WIN32 0 +#if LV_USE_FS_WIN32 + #define LV_FS_WIN32_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_WIN32_PATH "" /*Set the working directory. File/directory paths will be appended to it.*/ + #define LV_FS_WIN32_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ +#endif + +/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/ +#define LV_USE_FS_FATFS 0 +#if LV_USE_FS_FATFS + #define LV_FS_FATFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #define LV_FS_FATFS_CACHE_SIZE 0 /*>0 to cache this number of bytes in lv_fs_read()*/ +#endif + +/*PNG decoder library*/ +#define LV_USE_PNG 0 + +/*BMP decoder library*/ +#define LV_USE_BMP 0 + +/* JPG + split JPG decoder library. + * Split JPG is a custom format optimized for embedded systems. */ +#define LV_USE_SJPG 0 + +/*GIF decoder library*/ +#define LV_USE_GIF 0 + +/*QR code library*/ +#define LV_USE_QRCODE 0 + +/*FreeType library*/ +#define LV_USE_FREETYPE 0 +#if LV_USE_FREETYPE + /*Memory used by FreeType to cache characters [bytes] (-1: no caching)*/ + #define LV_FREETYPE_CACHE_SIZE (16 * 1024) + #if LV_FREETYPE_CACHE_SIZE >= 0 + /* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */ + /* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */ + /* if font size >= 256, must be configured as image cache */ + #define LV_FREETYPE_SBIT_CACHE 0 + /* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */ + /* (0:use system defaults) */ + #define LV_FREETYPE_CACHE_FT_FACES 0 + #define LV_FREETYPE_CACHE_FT_SIZES 0 + #endif +#endif + +/*Rlottie library*/ +#define LV_USE_RLOTTIE 0 + +/*FFmpeg library for image decoding and playing videos + *Supports all major image formats so do not enable other image decoder with it*/ +#define LV_USE_FFMPEG 0 +#if LV_USE_FFMPEG + /*Dump input information to stderr*/ + #define LV_FFMPEG_DUMP_FORMAT 0 +#endif + +/*----------- + * Others + *----------*/ + +/*1: Enable API to take snapshot for object*/ +#define LV_USE_SNAPSHOT 0 + +/*1: Enable Monkey test*/ +#define LV_USE_MONKEY 0 + +/*1: Enable grid navigation*/ +#define LV_USE_GRIDNAV 0 + +/*1: Enable lv_obj fragment*/ +#define LV_USE_FRAGMENT 0 + +/*1: Support using images as font in label or span widgets */ +#define LV_USE_IMGFONT 0 + +/*1: Enable a published subscriber based messaging system */ +#define LV_USE_MSG 0 + +/*1: Enable Pinyin input method*/ +/*Requires: lv_keyboard*/ +#define LV_USE_IME_PINYIN 0 +#if LV_USE_IME_PINYIN + /*1: Use default thesaurus*/ + /*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/ + #define LV_IME_PINYIN_USE_DEFAULT_DICT 1 + /*Set the maximum number of candidate panels that can be displayed*/ + /*This needs to be adjusted according to the size of the screen*/ + #define LV_IME_PINYIN_CAND_TEXT_NUM 6 + + /*Use 9 key input(k9)*/ + #define LV_IME_PINYIN_USE_K9_MODE 1 + #if LV_IME_PINYIN_USE_K9_MODE == 1 + #define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3 + #endif // LV_IME_PINYIN_USE_K9_MODE +#endif + +/*================== +* EXAMPLES +*==================*/ + +/*Enable the examples to be built with the library*/ +#define LV_BUILD_EXAMPLES 0 + +/*=================== + * DEMO USAGE + ====================*/ + +/*Show some widget. It might be required to increase `LV_MEM_SIZE` */ +#define LV_USE_DEMO_WIDGETS 0 +#if LV_USE_DEMO_WIDGETS +#define LV_DEMO_WIDGETS_SLIDESHOW 0 +#endif + +/*Demonstrate the usage of encoder and keyboard*/ +#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0 + +/*Benchmark your system*/ +#define LV_USE_DEMO_BENCHMARK 0 +#if LV_USE_DEMO_BENCHMARK +/*Use RGB565A8 images with 16 bit color depth instead of ARGB8565*/ +#define LV_DEMO_BENCHMARK_RGB565A8 0 +#endif + +/*Stress test for LVGL*/ +#define LV_USE_DEMO_STRESS 0 + +/*Music player demo*/ +#define LV_USE_DEMO_MUSIC 0 +#if LV_USE_DEMO_MUSIC + #define LV_DEMO_MUSIC_SQUARE 0 + #define LV_DEMO_MUSIC_LANDSCAPE 0 + #define LV_DEMO_MUSIC_ROUND 0 + #define LV_DEMO_MUSIC_LARGE 0 + #define LV_DEMO_MUSIC_AUTO_PLAY 0 +#endif + +/*--END OF LV_CONF_H--*/ + +#endif /*LV_CONF_H*/ diff --git a/src/ui/c/lv_drv_conf.h b/src/ui/c/lv_drv_conf.h new file mode 100644 index 0000000..c892165 --- /dev/null +++ b/src/ui/c/lv_drv_conf.h @@ -0,0 +1,487 @@ +/** + * LVGL display/touch drivers config file for v8.3.0 + * see lib/lvgl/lv_conf_template.h for initial values + */ + +#ifndef LV_DRV_CONF_H +#define LV_DRV_CONF_H + +#include "lv_conf.h" + +/********************* + * DELAY INTERFACE + *********************/ +#define LV_DRV_DELAY_INCLUDE /*Dummy include by default*/ +#define LV_DRV_DELAY_US(us) /*delay_us(us)*/ /*Delay the given number of microseconds*/ +#define LV_DRV_DELAY_MS(ms) /*delay_ms(ms)*/ /*Delay the given number of milliseconds*/ + +/********************* + * DISPLAY INTERFACE + *********************/ + +/*------------ + * Common + *------------*/ +#define LV_DRV_DISP_INCLUDE /*Dummy include by default*/ +#define LV_DRV_DISP_CMD_DATA(val) /*pin_x_set(val)*/ /*Set the command/data pin to 'val'*/ +#define LV_DRV_DISP_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/ + +/*--------- + * SPI + *---------*/ +#define LV_DRV_DISP_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/ +#define LV_DRV_DISP_SPI_WR_BYTE(data) /*spi_wr(data)*/ /*Write a byte the SPI bus*/ +#define LV_DRV_DISP_SPI_WR_ARRAY(adr, n) /*spi_wr_mem(adr, n)*/ /*Write 'n' bytes to SPI bus from 'adr'*/ + +/*------------------ + * Parallel port + *-----------------*/ +#define LV_DRV_DISP_PAR_CS(val) /*par_cs_set(val)*/ /*Set the Parallel port's Chip select to 'val'*/ +#define LV_DRV_DISP_PAR_SLOW /*par_slow()*/ /*Set low speed on the parallel port*/ +#define LV_DRV_DISP_PAR_FAST /*par_fast()*/ /*Set high speed on the parallel port*/ +#define LV_DRV_DISP_PAR_WR_WORD(data) /*par_wr(data)*/ /*Write a word to the parallel port*/ +#define LV_DRV_DISP_PAR_WR_ARRAY(adr, n) /*par_wr_mem(adr,n)*/ /*Write 'n' bytes to Parallel ports from 'adr'*/ + +/*************************** + * INPUT DEVICE INTERFACE + ***************************/ + +/*---------- + * Common + *----------*/ +#define LV_DRV_INDEV_INCLUDE /*Dummy include by default*/ +#define LV_DRV_INDEV_RST(val) /*pin_x_set(val)*/ /*Set the reset pin to 'val'*/ +#define LV_DRV_INDEV_IRQ_READ 0 /*pn_x_read()*/ /*Read the IRQ pin*/ + +/*--------- + * SPI + *---------*/ +#define LV_DRV_INDEV_SPI_CS(val) /*spi_cs_set(val)*/ /*Set the SPI's Chip select to 'val'*/ +#define LV_DRV_INDEV_SPI_XCHG_BYTE(data) 0 /*spi_xchg(val)*/ /*Write 'val' to SPI and give the read value*/ + +/*--------- + * I2C + *---------*/ +#define LV_DRV_INDEV_I2C_START /*i2c_start()*/ /*Make an I2C start*/ +#define LV_DRV_INDEV_I2C_STOP /*i2c_stop()*/ /*Make an I2C stop*/ +#define LV_DRV_INDEV_I2C_RESTART /*i2c_restart()*/ /*Make an I2C restart*/ +#define LV_DRV_INDEV_I2C_WR(data) /*i2c_wr(data)*/ /*Write a byte to the I1C bus*/ +#define LV_DRV_INDEV_I2C_READ(last_read) 0 /*i2c_rd()*/ /*Read a byte from the I2C bud*/ + + +/********************* + * DISPLAY DRIVERS + *********************/ + +/*------------------- + * SDL + *-------------------*/ + +/* SDL based drivers for display, mouse, mousewheel and keyboard*/ +#ifndef USE_SDL +# define USE_SDL 0 +#endif + +/* Hardware accelerated SDL driver */ +#ifndef USE_SDL_GPU +# define USE_SDL_GPU 0 +#endif + +#if USE_SDL || USE_SDL_GPU +# define SDL_HOR_RES 800 +# define SDL_VER_RES 480 + +/* Scale window by this factor (useful when simulating small screens) */ +# define SDL_ZOOM 1 + +/* Used to test true double buffering with only address changing. + * Use 2 draw buffers, bith with SDL_HOR_RES x SDL_VER_RES size*/ +# define SDL_DOUBLE_BUFFERED 0 + +/*Eclipse: Visual Studio: */ +# define SDL_INCLUDE_PATH + +/*Open two windows to test multi display support*/ +# define SDL_DUAL_DISPLAY 0 +#endif + +/*------------------- + * Monitor of PC + *-------------------*/ + +/*DEPRECATED: Use the SDL driver instead. */ +#ifndef USE_MONITOR +# define USE_MONITOR 0 +#endif + +#if USE_MONITOR +# define MONITOR_HOR_RES 480 +# define MONITOR_VER_RES 320 + +/* Scale window by this factor (useful when simulating small screens) */ +# define MONITOR_ZOOM 1 + +/* Used to test true double buffering with only address changing. + * Use 2 draw buffers, bith with MONITOR_HOR_RES x MONITOR_VER_RES size*/ +# define MONITOR_DOUBLE_BUFFERED 0 + +/*Eclipse: Visual Studio: */ +# define MONITOR_SDL_INCLUDE_PATH + +/*Open two windows to test multi display support*/ +# define MONITOR_DUAL 0 +#endif + +/*----------------------------------- + * Native Windows (including mouse) + *----------------------------------*/ +#ifndef USE_WINDOWS +# define USE_WINDOWS 0 +#endif + +#if USE_WINDOWS +# define WINDOW_HOR_RES 480 +# define WINDOW_VER_RES 320 +#endif + +/*---------------------------- + * Native Windows (win32drv) + *---------------------------*/ +#ifndef USE_WIN32DRV +# define USE_WIN32DRV 0 +#endif + +#if USE_WIN32DRV +/* Scale window by this factor (useful when simulating small screens) */ +# define WIN32DRV_MONITOR_ZOOM 1 +#endif + +/*---------------------------------------- + * GTK drivers (monitor, mouse, keyboard + *---------------------------------------*/ +#ifndef USE_GTK +# define USE_GTK 0 +#endif + +/*---------------------------------------- + * Wayland drivers (monitor, mouse, keyboard, touchscreen) + *---------------------------------------*/ +#ifndef USE_WAYLAND +# define USE_WAYLAND 0 +#endif + +#if USE_WAYLAND +/* Support for client-side decorations */ +# ifndef LV_WAYLAND_CLIENT_SIDE_DECORATIONS +# define LV_WAYLAND_CLIENT_SIDE_DECORATIONS 1 +# endif +/* Support for (deprecated) wl-shell protocol */ +# ifndef LV_WAYLAND_WL_SHELL +# define LV_WAYLAND_WL_SHELL 1 +# endif +/* Support for xdg-shell protocol */ +# ifndef LV_WAYLAND_XDG_SHELL +# define LV_WAYLAND_XDG_SHELL 0 +# endif +#endif + +/*---------------- + * SSD1963 + *--------------*/ +#ifndef USE_SSD1963 +# define USE_SSD1963 0 +#endif + +#if USE_SSD1963 +# define SSD1963_HOR_RES LV_HOR_RES +# define SSD1963_VER_RES LV_VER_RES +# define SSD1963_HT 531 +# define SSD1963_HPS 43 +# define SSD1963_LPS 8 +# define SSD1963_HPW 10 +# define SSD1963_VT 288 +# define SSD1963_VPS 12 +# define SSD1963_FPS 4 +# define SSD1963_VPW 10 +# define SSD1963_HS_NEG 0 /*Negative hsync*/ +# define SSD1963_VS_NEG 0 /*Negative vsync*/ +# define SSD1963_ORI 0 /*0, 90, 180, 270*/ +# define SSD1963_COLOR_DEPTH 16 +#endif + +/*---------------- + * R61581 + *--------------*/ +#ifndef USE_R61581 +# define USE_R61581 0 +#endif + +#if USE_R61581 +# define R61581_HOR_RES LV_HOR_RES +# define R61581_VER_RES LV_VER_RES +# define R61581_HSPL 0 /*HSYNC signal polarity*/ +# define R61581_HSL 10 /*HSYNC length (Not Implemented)*/ +# define R61581_HFP 10 /*Horitontal Front poarch (Not Implemented)*/ +# define R61581_HBP 10 /*Horitontal Back poarch (Not Implemented */ +# define R61581_VSPL 0 /*VSYNC signal polarity*/ +# define R61581_VSL 10 /*VSYNC length (Not Implemented)*/ +# define R61581_VFP 8 /*Vertical Front poarch*/ +# define R61581_VBP 8 /*Vertical Back poarch */ +# define R61581_DPL 0 /*DCLK signal polarity*/ +# define R61581_EPL 1 /*ENABLE signal polarity*/ +# define R61581_ORI 0 /*0, 180*/ +# define R61581_LV_COLOR_DEPTH 16 /*Fix 16 bit*/ +#endif + +/*------------------------------ + * ST7565 (Monochrome, low res.) + *-----------------------------*/ +#ifndef USE_ST7565 +# define USE_ST7565 0 +#endif + +#if USE_ST7565 +/*No settings*/ +#endif /*USE_ST7565*/ + +/*------------------------------ + * GC9A01 (color, low res.) + *-----------------------------*/ +#ifndef USE_GC9A01 +# define USE_GC9A01 0 +#endif + +#if USE_GC9A01 +/*No settings*/ +#endif /*USE_GC9A01*/ + +/*------------------------------------------ + * UC1610 (4 gray 160*[104|128]) + * (EA DOGXL160 160x104 tested) + *-----------------------------------------*/ +#ifndef USE_UC1610 +# define USE_UC1610 0 +#endif + +#if USE_UC1610 +# define UC1610_HOR_RES LV_HOR_RES +# define UC1610_VER_RES LV_VER_RES +# define UC1610_INIT_CONTRAST 33 /* init contrast, values in [%] */ +# define UC1610_INIT_HARD_RST 0 /* 1 : hardware reset at init, 0 : software reset */ +# define UC1610_TOP_VIEW 0 /* 0 : Bottom View, 1 : Top View */ +#endif /*USE_UC1610*/ + +/*------------------------------------------------- + * SHARP memory in pixel monochrome display series + * LS012B7DD01 (184x38 pixels.) + * LS013B7DH03 (128x128 pixels.) + * LS013B7DH05 (144x168 pixels.) + * LS027B7DH01 (400x240 pixels.) (tested) + * LS032B7DD02 (336x536 pixels.) + * LS044Q7DH01 (320x240 pixels.) + *------------------------------------------------*/ +#ifndef USE_SHARP_MIP +# define USE_SHARP_MIP 0 +#endif + +#if USE_SHARP_MIP +# define SHARP_MIP_HOR_RES LV_HOR_RES +# define SHARP_MIP_VER_RES LV_VER_RES +# define SHARP_MIP_SOFT_COM_INVERSION 0 +# define SHARP_MIP_REV_BYTE(b) /*((uint8_t) __REV(__RBIT(b)))*/ /*Architecture / compiler dependent byte bits order reverse*/ +#endif /*USE_SHARP_MIP*/ + +/*------------------------------------------------- + * ILI9341 240X320 TFT LCD + *------------------------------------------------*/ +#ifndef USE_ILI9341 +# define USE_ILI9341 0 +#endif + +#if USE_ILI9341 +# define ILI9341_HOR_RES LV_HOR_RES +# define ILI9341_VER_RES LV_VER_RES +# define ILI9341_GAMMA 1 +# define ILI9341_TEARING 0 +#endif /*USE_ILI9341*/ + +/*----------------------------------------- + * Linux frame buffer device (/dev/fbx) + *-----------------------------------------*/ +#ifndef USE_FBDEV +# define USE_FBDEV 0 +#endif + +#if USE_FBDEV +# define FBDEV_PATH "/dev/fb0" +#endif + +/*----------------------------------------- + * FreeBSD frame buffer device (/dev/fbx) + *.........................................*/ +#ifndef USE_BSD_FBDEV +# define USE_BSD_FBDEV 0 +#endif + +#if USE_BSD_FBDEV +# define FBDEV_PATH "/dev/fb0" +#endif + +/*----------------------------------------- + * DRM/KMS device (/dev/dri/cardX) + *-----------------------------------------*/ +// TODO: consider switching to DRM? +// see https://forum.lvgl.io/t/drm-driver-is-slow/3479 +#ifndef USE_DRM +# define USE_DRM 0 +#endif + +#if USE_DRM +# define DRM_CARD "/dev/dri/card0" +# define DRM_CONNECTOR_ID -1 /* -1 for the first connected one */ +#endif + +/********************* + * INPUT DEVICES + *********************/ + +/*-------------- + * XPT2046 + *--------------*/ +#ifndef USE_XPT2046 +# define USE_XPT2046 0 +#endif + +#if USE_XPT2046 +# define XPT2046_HOR_RES 480 +# define XPT2046_VER_RES 320 +# define XPT2046_X_MIN 200 +# define XPT2046_Y_MIN 200 +# define XPT2046_X_MAX 3800 +# define XPT2046_Y_MAX 3800 +# define XPT2046_AVG 4 +# define XPT2046_X_INV 0 +# define XPT2046_Y_INV 0 +# define XPT2046_XY_SWAP 0 +#endif + +/*----------------- + * FT5406EE8 + *-----------------*/ +#ifndef USE_FT5406EE8 +# define USE_FT5406EE8 0 +#endif + +#if USE_FT5406EE8 +# define FT5406EE8_I2C_ADR 0x38 /*7 bit address*/ +#endif + +/*--------------- + * AD TOUCH + *--------------*/ +#ifndef USE_AD_TOUCH +# define USE_AD_TOUCH 0 +#endif + +#if USE_AD_TOUCH +/*No settings*/ +#endif + + +/*--------------------------------------- + * Mouse or touchpad on PC (using SDL) + *-------------------------------------*/ +/*DEPRECATED: Use the SDL driver instead. */ +#ifndef USE_MOUSE +# define USE_MOUSE 0 +#endif + +#if USE_MOUSE +/*No settings*/ +#endif + +/*------------------------------------------- + * Mousewheel as encoder on PC (using SDL) + *------------------------------------------*/ +/*DEPRECATED: Use the SDL driver instead. */ +#ifndef USE_MOUSEWHEEL +# define USE_MOUSEWHEEL 0 +#endif + +#if USE_MOUSEWHEEL +/*No settings*/ +#endif + +/*------------------------------------------------- + * Touchscreen, mouse/touchpad or keyboard as libinput interface (for Linux based systems) + *------------------------------------------------*/ +#ifndef USE_LIBINPUT +# define USE_LIBINPUT 0 +#endif + +#ifndef USE_BSD_LIBINPUT +# define USE_BSD_LIBINPUT 0 +#endif + +#if USE_LIBINPUT || USE_BSD_LIBINPUT +/*If only a single device of the same type is connected, you can also auto detect it, e.g.: + *#define LIBINPUT_NAME libinput_find_dev(LIBINPUT_CAPABILITY_TOUCH, false)*/ +# define LIBINPUT_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/ + +#endif /*USE_LIBINPUT || USE_BSD_LIBINPUT*/ + +/*------------------------------------------------- + * Mouse or touchpad as evdev interface (for Linux based systems) + *------------------------------------------------*/ +#ifndef USE_EVDEV +# define USE_EVDEV 0 +#endif + +#ifndef USE_BSD_EVDEV +# define USE_BSD_EVDEV 0 +#endif + +#if USE_EVDEV || USE_BSD_EVDEV +# define EVDEV_NAME "/dev/input/event0" /*You can use the "evtest" Linux tool to get the list of devices and test them*/ +# define EVDEV_SWAP_AXES 0 /*Swap the x and y axes of the touchscreen*/ + +# define EVDEV_CALIBRATE 0 /*Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis*/ + +# if EVDEV_CALIBRATE +# define EVDEV_HOR_MIN 0 /*to invert axis swap EVDEV_XXX_MIN by EVDEV_XXX_MAX*/ +# define EVDEV_HOR_MAX 4096 /*"evtest" Linux tool can help to get the correct calibraion values>*/ +# define EVDEV_VER_MIN 0 +# define EVDEV_VER_MAX 4096 +# endif /*EVDEV_CALIBRATE*/ +#endif /*USE_EVDEV*/ + +/*------------------------------------------------- + * Full keyboard support for evdev and libinput interface + *------------------------------------------------*/ +# ifndef USE_XKB +# define USE_XKB 0 +# endif + +#if USE_LIBINPUT || USE_BSD_LIBINPUT || USE_EVDEV || USE_BSD_EVDEV +# if USE_XKB +# define XKB_KEY_MAP { .rules = NULL, \ + .model = "pc101", \ + .layout = "us", \ + .variant = NULL, \ + .options = NULL } /*"setxkbmap -query" can help find the right values for your keyboard*/ +# endif /*USE_XKB*/ +#endif /*USE_LIBINPUT || USE_BSD_LIBINPUT || USE_EVDEV || USE_BSD_EVDEV*/ + +/*------------------------------- + * Keyboard of a PC (using SDL) + *------------------------------*/ +/*DEPRECATED: Use the SDL driver instead. */ +#ifndef USE_KEYBOARD +# define USE_KEYBOARD 0 +#endif + +#if USE_KEYBOARD +/*No settings*/ +#endif + +#endif /*LV_DRV_CONF_H*/ diff --git a/src/ui/c/lv_font_courierprimecode_14.c b/src/ui/c/lv_font_courierprimecode_14.c new file mode 100644 index 0000000..f221153 --- /dev/null +++ b/src/ui/c/lv_font_courierprimecode_14.c @@ -0,0 +1,1676 @@ +/******************************************************************************* + * Size: 14 px + * Bpp: 4 + * Opts: --no-compress --no-prefilter --bpp 4 --size 14 --font courier-prime-code.ttf -r 0x20-0x7F,0xB0,0x2022 --font fa-brands-400.ttf -r 0xF287,0xF293,0xF379 --font fa-solid-900.ttf -r 0xF001,0xF008,0xF00B,0xF00C,0xF00D,0xF011,0xF013,0xF015,0xF019,0xF01C,0xF021,0xF026,0xF027,0xF028,0xF03E,0xF043,0xF048,0xF04B,0xF04C,0xF04D,0xF051,0xF052,0xF053,0xF054,0xF067,0xF068,0xF06E,0xF070,0xF071,0xF074,0xF077,0xF078,0xF079,0xF07B,0xF093,0xF095,0xF0C4,0xF0C5,0xF0C7,0xF0C9,0xF0E0,0xF0E7,0xF0EA,0xF0F3,0xF11C,0xF124,0xF158,0xF1EB,0xF240,0xF241,0xF242,0xF243,0xF244,0xF2ED,0xF304,0xF55A,0xF7C2,0xF177=>0xF8A2,0xE0B4,0xF0E7 --format lvgl -o lv_font_courierprimecode_14.c --force-fast-kern-format + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef LV_FONT_COURIERPRIMECODE_14 +#define LV_FONT_COURIERPRIMECODE_14 1 +#endif + +#if LV_FONT_COURIERPRIMECODE_14 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + + /* U+0021 "!" */ + 0x7e, 0x7, 0xd0, 0x6c, 0x5, 0xb0, 0x4a, 0x2, + 0x80, 0x0, 0x9, 0xf0, 0x9e, 0x0, + + /* U+0022 "\"" */ + 0x1, 0x0, 0x10, 0x2f, 0x70, 0xf9, 0xf, 0x50, + 0xe8, 0xf, 0x30, 0xc6, 0xc, 0x10, 0x93, + + /* U+0023 "#" */ + 0x0, 0xa, 0x30, 0xc0, 0x0, 0xd, 0x4, 0xa0, + 0xe, 0xff, 0xff, 0xfd, 0x1, 0x88, 0x2d, 0x31, + 0x0, 0xb3, 0xe, 0x0, 0x7f, 0xff, 0xff, 0xf6, + 0x4, 0xc2, 0x88, 0x20, 0x5, 0x80, 0xa3, 0x0, + 0x8, 0x40, 0xc0, 0x0, + + /* U+0024 "$" */ + 0x0, 0x38, 0x0, 0x0, 0x5, 0xa0, 0x0, 0x9, + 0xef, 0xb5, 0x8, 0xb2, 0x37, 0xa0, 0xb6, 0x0, + 0x0, 0x6, 0xfc, 0x96, 0x0, 0x3, 0x7a, 0xed, + 0x0, 0x0, 0x0, 0xf2, 0x86, 0x0, 0x3f, 0x15, + 0xdf, 0xff, 0x60, 0x0, 0x5a, 0x0, 0x0, 0x5, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+0025 "%" */ + 0x1c, 0xe5, 0x0, 0x0, 0x8, 0x71, 0xe0, 0x8, + 0x80, 0x87, 0x1e, 0x8, 0xc0, 0x1, 0xce, 0x58, + 0xc1, 0x0, 0x0, 0x7, 0xc1, 0x0, 0x0, 0x7, + 0xd2, 0xce, 0x50, 0x7, 0xd1, 0x86, 0x2d, 0x2, + 0xd1, 0x9, 0x61, 0xd0, 0x0, 0x0, 0x1d, 0xe5, + 0x0, + + /* U+0026 "&" */ + 0x2, 0xce, 0xa1, 0x0, 0xe7, 0x38, 0x40, 0x2e, + 0x0, 0x0, 0x1, 0xf0, 0x0, 0x0, 0xb, 0x90, + 0x3, 0x4, 0xfe, 0x60, 0xe2, 0xc6, 0x3e, 0x7d, + 0xe, 0x20, 0x5f, 0x70, 0xa9, 0x28, 0xfc, 0x1, + 0xcf, 0xc2, 0xb4, + + /* U+0027 "'" */ + 0x1, 0x9, 0xf0, 0x8e, 0x6, 0xc0, 0x39, 0x0, + + /* U+0028 "(" */ + 0x0, 0x28, 0x2, 0xe7, 0xc, 0x70, 0x4d, 0x0, + 0xa6, 0x0, 0xd2, 0x0, 0xf1, 0x0, 0xe2, 0x0, + 0xb4, 0x0, 0x6b, 0x0, 0xe, 0x40, 0x4, 0xe3, + 0x0, 0x5c, + + /* U+0029 ")" */ + 0x6a, 0x0, 0x0, 0xba, 0x0, 0x0, 0xd5, 0x0, + 0x4, 0xc0, 0x0, 0xe, 0x10, 0x0, 0xb4, 0x0, + 0xa, 0x50, 0x0, 0xc4, 0x0, 0xe, 0x10, 0x6, + 0xb0, 0x2, 0xe3, 0x2, 0xe7, 0x0, 0x46, 0x0, + 0x0, + + /* U+002A "*" */ + 0x0, 0x1, 0x40, 0x0, 0x0, 0x6, 0xc0, 0x0, + 0x0, 0x5, 0xb0, 0x0, 0x2e, 0x74, 0x94, 0xc8, + 0x6, 0xad, 0xfb, 0x82, 0x0, 0x1d, 0xc4, 0x0, + 0x0, 0xb9, 0x2f, 0x30, 0x2, 0xe1, 0x9, 0x80, + + /* U+002B "+" */ + 0x0, 0x25, 0x0, 0x0, 0x4, 0xb0, 0x0, 0x0, + 0x4b, 0x0, 0xb, 0xff, 0xff, 0xe2, 0x12, 0x6b, + 0x21, 0x0, 0x4, 0xb0, 0x0, 0x0, 0x3a, 0x0, + 0x0, + + /* U+002C "," */ + 0x3, 0x50, 0xe, 0xe0, 0x1f, 0x80, 0x4f, 0x10, + 0x6a, 0x0, + + /* U+002D "-" */ + 0xbf, 0xff, 0xff, 0x21, 0x22, 0x22, 0x10, + + /* U+002E "." */ + 0x24, 0xb, 0xf1, 0xaf, 0x10, + + /* U+002F "/" */ + 0x0, 0x0, 0x2e, 0x0, 0x0, 0x7, 0xa0, 0x0, + 0x0, 0xd4, 0x0, 0x0, 0x4e, 0x0, 0x0, 0xa, + 0x80, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x6c, 0x0, + 0x0, 0xc, 0x60, 0x0, 0x2, 0xf0, 0x0, 0x0, + 0x8a, 0x0, 0x0, 0xd, 0x40, 0x0, 0x4, 0xe0, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x0, + + /* U+0030 "0" */ + 0x4, 0xdf, 0x80, 0x1, 0xe5, 0x3d, 0x60, 0x6a, + 0x0, 0xbd, 0xa, 0x60, 0x9b, 0xf0, 0xa6, 0x7c, + 0xf, 0x1a, 0xbe, 0x10, 0xf0, 0x6f, 0x30, 0x4d, + 0x1, 0xf6, 0x2c, 0x60, 0x4, 0xdf, 0x90, 0x0, + + /* U+0031 "1" */ + 0x0, 0x5c, 0x0, 0x1, 0xbe, 0xe0, 0x0, 0x59, + 0x2e, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x1e, + 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x1e, 0x0, + 0x0, 0x2, 0xe1, 0x0, 0x4f, 0xff, 0xff, 0x0, + + /* U+0032 "2" */ + 0x19, 0xef, 0x90, 0x59, 0x32, 0xd6, 0x0, 0x0, + 0x7a, 0x0, 0x0, 0xa7, 0x0, 0x5, 0xe1, 0x0, + 0x3e, 0x30, 0x2, 0xe5, 0x0, 0x1e, 0x71, 0x10, + 0x9f, 0xff, 0xfd, + + /* U+0033 "3" */ + 0x2a, 0xee, 0x80, 0x58, 0x23, 0xd5, 0x0, 0x0, + 0x88, 0x0, 0x1, 0xc5, 0x0, 0xcf, 0xd0, 0x0, + 0x1, 0xa9, 0x0, 0x0, 0x4c, 0x88, 0x22, 0xb9, + 0x2a, 0xef, 0xa0, + + /* U+0034 "4" */ + 0x0, 0x0, 0x9a, 0x0, 0x0, 0x3, 0xfb, 0x0, + 0x0, 0xc, 0x9b, 0x0, 0x0, 0x6c, 0x4b, 0x0, + 0x0, 0xe3, 0x4b, 0x0, 0x8, 0xa0, 0x4b, 0x0, + 0xf, 0xff, 0xff, 0xe2, 0x1, 0x22, 0x6c, 0x10, + 0x0, 0x0, 0x4a, 0x0, + + /* U+0035 "5" */ + 0x1f, 0xff, 0xf6, 0x2d, 0x11, 0x10, 0x3c, 0x0, + 0x0, 0x3e, 0xde, 0x90, 0x2a, 0x43, 0xc8, 0x0, + 0x0, 0x4d, 0x0, 0x0, 0x4d, 0x88, 0x23, 0xc8, + 0x2a, 0xef, 0x90, + + /* U+0036 "6" */ + 0x0, 0x3b, 0xe9, 0x0, 0x5e, 0x73, 0x10, 0x1e, + 0x20, 0x0, 0x6, 0xbb, 0xeb, 0x10, 0x8f, 0x63, + 0xbb, 0x9, 0xa0, 0x1, 0xf0, 0x7a, 0x0, 0x1f, + 0x1, 0xf5, 0x2a, 0xb0, 0x4, 0xdf, 0xb1, 0x0, + + /* U+0037 "7" */ + 0x8f, 0xff, 0xff, 0x0, 0x11, 0x16, 0xb0, 0x0, + 0x0, 0xb5, 0x0, 0x0, 0x1f, 0x0, 0x0, 0x7, + 0x90, 0x0, 0x0, 0xd4, 0x0, 0x0, 0x3e, 0x0, + 0x0, 0x9, 0x80, 0x0, 0x0, 0xd2, 0x0, 0x0, + + /* U+0038 "8" */ + 0x4, 0xdf, 0x90, 0x1e, 0x52, 0xc7, 0x4c, 0x0, + 0x6a, 0x1e, 0x20, 0xb7, 0x7, 0xff, 0xd0, 0x3d, + 0x42, 0xaa, 0x88, 0x0, 0x2e, 0x5e, 0x42, 0xab, + 0x7, 0xef, 0xb1, + + /* U+0039 "9" */ + 0x8, 0xef, 0x90, 0x6d, 0x32, 0xb7, 0xa7, 0x0, + 0x3d, 0x7c, 0x10, 0x9f, 0xa, 0xff, 0xaf, 0x0, + 0x11, 0x6c, 0x0, 0x1, 0xe6, 0x2, 0x5d, 0xb0, + 0x3f, 0xd7, 0x0, + + /* U+003A ":" */ + 0xaf, 0x1b, 0xf1, 0x24, 0x0, 0x0, 0x24, 0xb, + 0xf1, 0xaf, 0x10, + + /* U+003B ";" */ + 0xa, 0xf1, 0xb, 0xf1, 0x2, 0x40, 0x0, 0x0, + 0x3, 0x51, 0xc, 0xf1, 0xf, 0xa0, 0x2f, 0x30, + 0x3c, 0x0, + + /* U+003C "<" */ + 0x0, 0x0, 0x4, 0xb1, 0x0, 0x3, 0xbe, 0x60, + 0x2, 0xae, 0x70, 0x0, 0x1f, 0xc0, 0x0, 0x0, + 0x4, 0xcd, 0x50, 0x0, 0x0, 0x5, 0xdc, 0x40, + 0x0, 0x0, 0x6, 0xd1, + + /* U+003D "=" */ + 0xbf, 0xff, 0xfe, 0x21, 0x22, 0x22, 0x10, 0x0, + 0x0, 0x0, 0xb, 0xff, 0xff, 0xe2, 0x12, 0x22, + 0x21, 0x0, + + /* U+003E ">" */ + 0x97, 0x0, 0x0, 0x2, 0xbe, 0x60, 0x0, 0x0, + 0x3b, 0xd5, 0x0, 0x0, 0x6, 0xf7, 0x0, 0x29, + 0xe7, 0x1, 0x9f, 0x81, 0x0, 0xa9, 0x10, 0x0, + 0x0, + + /* U+003F "?" */ + 0x8, 0xde, 0x80, 0x1a, 0x43, 0xc6, 0x0, 0x0, + 0x89, 0x0, 0x2, 0xd5, 0x0, 0x6f, 0x80, 0x0, + 0x97, 0x0, 0x0, 0x75, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x97, 0x0, 0x0, 0xc9, 0x0, + + /* U+0040 "@" */ + 0x0, 0x5c, 0xec, 0x40, 0x7, 0xb2, 0x2, 0xc4, + 0x1d, 0x9, 0xd9, 0x3b, 0x76, 0x5b, 0x3e, 0xd, + 0x93, 0xa4, 0x4b, 0xc, 0x93, 0xb3, 0xba, 0x3b, + 0x77, 0x5e, 0x6b, 0xd3, 0x1d, 0x40, 0x1, 0x0, + 0x2, 0xbe, 0xea, 0x0, + + /* U+0041 "A" */ + 0x0, 0x8, 0xd0, 0x0, 0x0, 0xe, 0xb4, 0x0, + 0x0, 0x4b, 0x5a, 0x0, 0x0, 0xa5, 0xe, 0x0, + 0x0, 0xe0, 0xa, 0x50, 0x5, 0xff, 0xff, 0xa0, + 0xa, 0x62, 0x22, 0xe0, 0xf, 0x10, 0x0, 0xa5, + 0x3b, 0x0, 0x0, 0x59, + + /* U+0042 "B" */ + 0x8f, 0xff, 0xc2, 0x9, 0x71, 0x19, 0xa0, 0x96, + 0x0, 0x3d, 0x9, 0x60, 0x8, 0xa0, 0x9f, 0xff, + 0xf4, 0x9, 0x72, 0x25, 0xe1, 0x96, 0x0, 0xc, + 0x59, 0x71, 0x14, 0xf2, 0x8f, 0xff, 0xe6, 0x0, + + /* U+0043 "C" */ + 0x4, 0xcf, 0xd8, 0x2, 0xf6, 0x24, 0xa3, 0xa7, + 0x0, 0x0, 0xe, 0x20, 0x0, 0x0, 0xf1, 0x0, + 0x0, 0xe, 0x20, 0x0, 0x0, 0xa7, 0x0, 0x0, + 0x2, 0xf6, 0x24, 0xa3, 0x4, 0xcf, 0xd8, 0x0, + + /* U+0044 "D" */ + 0xbf, 0xfe, 0x90, 0xc, 0x41, 0x2b, 0xb0, 0xc3, + 0x0, 0xe, 0x2c, 0x30, 0x0, 0xa6, 0xc3, 0x0, + 0x8, 0x7c, 0x30, 0x0, 0xa6, 0xc3, 0x0, 0xe, + 0x2c, 0x41, 0x2b, 0xb0, 0xbf, 0xfe, 0x90, 0x0, + + /* U+0045 "E" */ + 0x6f, 0xff, 0xfe, 0x7, 0x91, 0x11, 0x0, 0x79, + 0x0, 0x0, 0x7, 0x90, 0x0, 0x0, 0x7f, 0xff, + 0xe0, 0x7, 0x92, 0x21, 0x0, 0x79, 0x0, 0x0, + 0x7, 0x91, 0x11, 0x0, 0x6f, 0xff, 0xff, 0x0, + + /* U+0046 "F" */ + 0x4f, 0xff, 0xff, 0x5, 0xb1, 0x11, 0x0, 0x5b, + 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, 0x5f, 0xff, + 0xe3, 0x5, 0xb2, 0x21, 0x0, 0x5b, 0x0, 0x0, + 0x5, 0xb0, 0x0, 0x0, 0x4a, 0x0, 0x0, 0x0, + + /* U+0047 "G" */ + 0x0, 0x5d, 0xfd, 0x80, 0x5, 0xe5, 0x24, 0x91, + 0xe, 0x40, 0x0, 0x0, 0x2e, 0x0, 0x0, 0x0, + 0x3d, 0x0, 0xcf, 0xe5, 0x2e, 0x0, 0x12, 0xa6, + 0xe, 0x30, 0x0, 0xa6, 0x6, 0xe4, 0x24, 0xd6, + 0x0, 0x6d, 0xfd, 0x80, + + /* U+0048 "H" */ + 0xb2, 0x0, 0xc, 0x2c, 0x30, 0x0, 0xd3, 0xc3, + 0x0, 0xd, 0x3c, 0x30, 0x0, 0xd3, 0xcf, 0xff, + 0xff, 0x3c, 0x52, 0x22, 0xd3, 0xc3, 0x0, 0xd, + 0x3c, 0x30, 0x0, 0xd3, 0xb2, 0x0, 0xc, 0x20, + + /* U+0049 "I" */ + 0x6f, 0xff, 0xfc, 0x0, 0x15, 0xb1, 0x0, 0x0, + 0x5b, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, 0x5b, + 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, 0x5b, 0x0, + 0x0, 0x15, 0xb1, 0x0, 0x8f, 0xff, 0xfe, 0x0, + + /* U+004A "J" */ + 0x5, 0xff, 0xf7, 0x0, 0x1, 0x88, 0x0, 0x0, + 0x88, 0x0, 0x0, 0x88, 0x0, 0x0, 0x88, 0x0, + 0x0, 0x88, 0x0, 0x0, 0x87, 0x88, 0x23, 0xe4, + 0x2b, 0xee, 0x80, + + /* U+004B "K" */ + 0x76, 0x0, 0x1d, 0x38, 0x80, 0xc, 0x90, 0x88, + 0xb, 0xb0, 0x8, 0x89, 0xc0, 0x0, 0x8e, 0xfc, + 0x0, 0x8, 0xe2, 0xc7, 0x0, 0x88, 0x2, 0xf3, + 0x8, 0x80, 0x6, 0xd0, 0x77, 0x0, 0xa, 0x50, + + /* U+004C "L" */ + 0x4a, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, 0x5b, + 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, 0x5b, 0x0, + 0x0, 0x5, 0xb0, 0x0, 0x0, 0x5b, 0x0, 0x0, + 0x5, 0xb1, 0x11, 0x0, 0x4f, 0xff, 0xff, 0x0, + + /* U+004D "M" */ + 0xb, 0x50, 0x0, 0xd2, 0xd, 0xd0, 0x6, 0xf3, + 0xd, 0xe3, 0xd, 0xe4, 0xe, 0x8a, 0x4c, 0xb4, + 0xe, 0x2e, 0xc5, 0xb4, 0xe, 0x18, 0xe0, 0xb5, + 0xf, 0x0, 0x20, 0xa5, 0xf, 0x0, 0x0, 0xa6, + 0xe, 0x0, 0x0, 0x85, + + /* U+004E "N" */ + 0xb7, 0x0, 0xb, 0x2c, 0xf1, 0x0, 0xc3, 0xcb, + 0xa0, 0xc, 0x3c, 0x3d, 0x40, 0xc3, 0xc3, 0x5d, + 0xc, 0x3c, 0x30, 0xb7, 0xc3, 0xc3, 0x2, 0xee, + 0x3c, 0x30, 0x8, 0xf3, 0xb2, 0x0, 0xd, 0x20, + + /* U+004F "O" */ + 0x0, 0x8e, 0xfb, 0x20, 0x8, 0xc3, 0x28, 0xe0, + 0x1f, 0x10, 0x0, 0xb6, 0x4c, 0x0, 0x0, 0x5a, + 0x5b, 0x0, 0x0, 0x4c, 0x4c, 0x0, 0x0, 0x5a, + 0x1f, 0x10, 0x0, 0xb7, 0x9, 0xc3, 0x28, 0xe0, + 0x0, 0x8e, 0xfb, 0x20, + + /* U+0050 "P" */ + 0x5f, 0xff, 0xc3, 0x6, 0xa1, 0x17, 0xe0, 0x6a, + 0x0, 0xd, 0x46, 0xa0, 0x0, 0xc4, 0x6a, 0x0, + 0x5f, 0x16, 0xff, 0xfe, 0x50, 0x6a, 0x21, 0x0, + 0x6, 0xa0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, + + /* U+0051 "Q" */ + 0x0, 0x8e, 0xfb, 0x20, 0x8, 0xc3, 0x28, 0xe0, + 0x1f, 0x10, 0x0, 0xb6, 0x4c, 0x0, 0x0, 0x5a, + 0x5b, 0x0, 0x0, 0x4c, 0x4c, 0x0, 0x10, 0x5b, + 0x1f, 0x10, 0xe3, 0xb7, 0x9, 0xc3, 0x8e, 0xe0, + 0x0, 0x8e, 0xfe, 0x70, 0x0, 0x0, 0x3, 0xc0, + + /* U+0052 "R" */ + 0x5f, 0xff, 0xc2, 0x6, 0xa1, 0x18, 0xd0, 0x6a, + 0x0, 0xf, 0x6, 0xa0, 0x6, 0xe0, 0x6f, 0xff, + 0xe4, 0x6, 0xa2, 0xa8, 0x0, 0x6a, 0x1, 0xf2, + 0x6, 0xa0, 0x8, 0xa0, 0x59, 0x0, 0xd, 0x10, + + /* U+0053 "S" */ + 0x1a, 0xfe, 0xc5, 0x9, 0xb2, 0x26, 0xa0, 0xc4, + 0x0, 0x0, 0x9, 0xd5, 0x20, 0x0, 0x7, 0xcf, + 0xe5, 0x0, 0x0, 0x5, 0xf1, 0x0, 0x0, 0xd, + 0x3a, 0x83, 0x26, 0xf1, 0x3a, 0xef, 0xc4, 0x0, + + /* U+0054 "T" */ + 0x1f, 0xff, 0xff, 0xf7, 0x0, 0x15, 0xb1, 0x10, + 0x0, 0x5, 0xb0, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x5, 0xb0, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x5, 0xb0, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x4, 0xa0, 0x0, + + /* U+0055 "U" */ + 0xb2, 0x0, 0xc, 0x2c, 0x30, 0x0, 0xd3, 0xc3, + 0x0, 0xd, 0x3c, 0x30, 0x0, 0xd3, 0xc3, 0x0, + 0xd, 0x3c, 0x30, 0x0, 0xd3, 0xb5, 0x0, 0xf, + 0x16, 0xd3, 0x29, 0xc0, 0x8, 0xef, 0xb2, 0x0, + + /* U+0056 "V" */ + 0x3b, 0x0, 0x0, 0x69, 0xf, 0x10, 0x0, 0xb5, + 0xa, 0x70, 0x1, 0xf0, 0x4, 0xc0, 0x6, 0xa0, + 0x0, 0xe2, 0xc, 0x50, 0x0, 0x97, 0x2f, 0x0, + 0x0, 0x4d, 0x7a, 0x0, 0x0, 0xe, 0xe4, 0x0, + 0x0, 0x7, 0xd0, 0x0, + + /* U+0057 "W" */ + 0x77, 0x0, 0x0, 0x1c, 0x69, 0x0, 0x0, 0x4b, + 0x4b, 0x5, 0xb0, 0x69, 0x2d, 0xb, 0xf1, 0x87, + 0xf, 0xe, 0xb5, 0xa5, 0xe, 0x6b, 0x5a, 0xb3, + 0xc, 0xd6, 0x1e, 0xe1, 0xa, 0xf1, 0xb, 0xf0, + 0x7, 0xb0, 0x5, 0xc0, + + /* U+0058 "X" */ + 0xa5, 0x0, 0xd, 0x24, 0xe1, 0x8, 0xb0, 0xa, + 0x92, 0xe2, 0x0, 0x1e, 0xd7, 0x0, 0x0, 0x9f, + 0x10, 0x0, 0x2e, 0xb9, 0x0, 0xb, 0x71, 0xe3, + 0x6, 0xd0, 0x6, 0xd0, 0xc3, 0x0, 0xb, 0x50, + + /* U+0059 "Y" */ + 0xd, 0x10, 0x0, 0x96, 0x9, 0xa0, 0x3, 0xe1, + 0x1, 0xe3, 0xd, 0x60, 0x0, 0x6d, 0x7c, 0x0, + 0x0, 0xc, 0xf3, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x5, 0xb0, 0x0, 0x0, 0x5, 0xb0, 0x0, + 0x0, 0x4, 0xa0, 0x0, + + /* U+005A "Z" */ + 0x9f, 0xff, 0xff, 0x0, 0x11, 0x1a, 0x90, 0x0, + 0x4, 0xe1, 0x0, 0x0, 0xd6, 0x0, 0x0, 0x8c, + 0x0, 0x0, 0x2f, 0x20, 0x0, 0xb, 0x80, 0x0, + 0x5, 0xe1, 0x11, 0x0, 0xcf, 0xff, 0xff, 0x20, + + /* U+005B "[" */ + 0xaf, 0xfd, 0xc5, 0x21, 0xc4, 0x0, 0xc4, 0x0, + 0xc4, 0x0, 0xc4, 0x0, 0xc4, 0x0, 0xc4, 0x0, + 0xc4, 0x0, 0xc4, 0x0, 0xc4, 0x0, 0xc4, 0x0, + 0xbf, 0xfd, 0x2, 0x21, + + /* U+005C "\\" */ + 0x87, 0x0, 0x0, 0x4, 0xe0, 0x0, 0x0, 0xd, + 0x40, 0x0, 0x0, 0x8a, 0x0, 0x0, 0x2, 0xf0, + 0x0, 0x0, 0xc, 0x60, 0x0, 0x0, 0x6c, 0x0, + 0x0, 0x0, 0xf2, 0x0, 0x0, 0xa, 0x80, 0x0, + 0x0, 0x4e, 0x0, 0x0, 0x0, 0xd4, 0x0, 0x0, + 0x7, 0xa0, 0x0, 0x0, 0x2e, 0x0, + + /* U+005D "]" */ + 0x7f, 0xfe, 0x10, 0x22, 0xe2, 0x0, 0xe, 0x20, + 0x0, 0xe2, 0x0, 0xe, 0x20, 0x0, 0xe2, 0x0, + 0xe, 0x20, 0x0, 0xe2, 0x0, 0xe, 0x20, 0x0, + 0xe2, 0x0, 0xe, 0x20, 0x0, 0xe2, 0x7f, 0xff, + 0x10, 0x22, 0x10, + + /* U+005E "^" */ + 0x0, 0x6c, 0x0, 0x0, 0xdd, 0x40, 0x6, 0xb4, + 0xc0, 0xd, 0x30, 0xd4, 0x4b, 0x0, 0x5a, + + /* U+005F "_" */ + 0x6f, 0xff, 0xff, 0xfc, 0x2, 0x22, 0x22, 0x21, + + /* U+0060 "`" */ + 0xa8, 0x0, 0x4e, 0xa0, 0x1, 0xa6, + + /* U+0061 "a" */ + 0x19, 0xef, 0xc2, 0x4a, 0x31, 0x9c, 0x0, 0x0, + 0x2e, 0x2b, 0xed, 0xbf, 0xc8, 0x22, 0x5f, 0xd5, + 0x2, 0xbf, 0x3d, 0xfc, 0x5d, + + /* U+0062 "b" */ + 0xa4, 0x0, 0x0, 0xb, 0x50, 0x0, 0x0, 0xb5, + 0x0, 0x0, 0xb, 0x7b, 0xfc, 0x30, 0xbe, 0x52, + 0x8e, 0xb, 0x80, 0x0, 0xd4, 0xb5, 0x0, 0xa, + 0x6b, 0x80, 0x0, 0xc4, 0xbf, 0x51, 0x8e, 0xa, + 0x5c, 0xfc, 0x30, + + /* U+0063 "c" */ + 0x6, 0xdf, 0xc6, 0x6, 0xe4, 0x25, 0xb1, 0xd4, + 0x0, 0x0, 0xf, 0x10, 0x0, 0x0, 0xd4, 0x0, + 0x0, 0x7, 0xe4, 0x25, 0xc3, 0x7, 0xef, 0xc6, + 0x0, + + /* U+0064 "d" */ + 0x0, 0x0, 0x0, 0xd0, 0x0, 0x0, 0x0, 0xf1, + 0x0, 0x0, 0x0, 0xf1, 0x0, 0x9f, 0xe5, 0xf1, + 0x8, 0xc2, 0x3c, 0xf1, 0xe, 0x30, 0x2, 0xf1, + 0xf, 0x0, 0x0, 0xf1, 0xe, 0x20, 0x1, 0xf1, + 0x9, 0xb1, 0x1c, 0xf1, 0x0, 0x9f, 0xe6, 0xc0, + + /* U+0065 "e" */ + 0x7, 0xef, 0xb2, 0x7, 0xe4, 0x28, 0xd0, 0xd5, + 0x0, 0xd, 0x4f, 0xee, 0xee, 0xf6, 0xd4, 0x11, + 0x11, 0x8, 0xb2, 0x13, 0x81, 0x9, 0xef, 0xd8, + 0x0, + + /* U+0066 "f" */ + 0x0, 0x1b, 0xfd, 0x50, 0xa, 0x92, 0x54, 0x0, + 0xe2, 0x0, 0x0, 0xf, 0x10, 0x0, 0x9f, 0xff, + 0xfc, 0x0, 0x2f, 0x32, 0x10, 0x0, 0xf1, 0x0, + 0x0, 0xf, 0x10, 0x0, 0x0, 0xf1, 0x0, 0x0, + 0xd, 0x10, 0x0, + + /* U+0067 "g" */ + 0x0, 0x9f, 0xe6, 0xc0, 0x8, 0xc1, 0x1b, 0xf1, + 0xe, 0x20, 0x1, 0xf1, 0xf, 0x0, 0x0, 0xf1, + 0xe, 0x30, 0x2, 0xf1, 0x8, 0xc2, 0x3c, 0xf1, + 0x0, 0x9f, 0xe6, 0xf1, 0x0, 0x0, 0x0, 0xf0, + 0x4, 0x52, 0x29, 0xc0, 0x5, 0xcf, 0xfb, 0x20, + + /* U+0068 "h" */ + 0x95, 0x0, 0x0, 0xa, 0x60, 0x0, 0x0, 0xa6, + 0x0, 0x0, 0xa, 0x67, 0xee, 0x50, 0xad, 0xb2, + 0x5f, 0xa, 0xd0, 0x0, 0xe2, 0xa7, 0x0, 0xe, + 0x2a, 0x60, 0x0, 0xe2, 0xa6, 0x0, 0xe, 0x29, + 0x50, 0x0, 0xd1, + + /* U+0069 "i" */ + 0x0, 0x5c, 0x0, 0x0, 0x5, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xff, 0xd0, 0x0, 0x0, 0x3e, + 0x0, 0x0, 0x2, 0xe0, 0x0, 0x0, 0x2e, 0x0, + 0x0, 0x2, 0xe0, 0x0, 0x1, 0x3e, 0x11, 0xa, + 0xff, 0xff, 0xf6, + + /* U+006A "j" */ + 0x0, 0x1, 0xf2, 0x0, 0x1, 0xd1, 0x0, 0x0, + 0x0, 0x1f, 0xff, 0xf2, 0x0, 0x11, 0xd2, 0x0, + 0x0, 0xd2, 0x0, 0x0, 0xd2, 0x0, 0x0, 0xd2, + 0x0, 0x0, 0xd2, 0x0, 0x0, 0xd2, 0x0, 0x0, + 0xe2, 0x88, 0x24, 0xf0, 0x2a, 0xee, 0x60, + + /* U+006B "k" */ + 0x58, 0x0, 0x0, 0x6, 0x90, 0x0, 0x0, 0x69, + 0x0, 0x0, 0x6, 0x90, 0x3, 0xd1, 0x69, 0x3, + 0xe5, 0x6, 0x94, 0xe4, 0x0, 0x6d, 0xfd, 0x10, + 0x6, 0xe3, 0x9c, 0x0, 0x69, 0x0, 0xba, 0x5, + 0x80, 0x0, 0xc3, + + /* U+006C "l" */ + 0x6f, 0xfc, 0x0, 0x0, 0x14, 0xd0, 0x0, 0x0, + 0x3d, 0x0, 0x0, 0x3, 0xd0, 0x0, 0x0, 0x3d, + 0x0, 0x0, 0x3, 0xd0, 0x0, 0x0, 0x3d, 0x0, + 0x0, 0x3, 0xd0, 0x0, 0x1, 0x4d, 0x11, 0xb, + 0xff, 0xff, 0xf5, + + /* U+006D "m" */ + 0x2a, 0xae, 0x4c, 0xe2, 0x2f, 0x66, 0xf3, 0x87, + 0x2f, 0x5, 0xd0, 0x79, 0x2e, 0x5, 0xb0, 0x79, + 0x2d, 0x5, 0xb0, 0x79, 0x2d, 0x5, 0xb0, 0x79, + 0x2c, 0x4, 0xa0, 0x68, + + /* U+006E "n" */ + 0x94, 0x7e, 0xe5, 0xa, 0xd9, 0x13, 0xf0, 0xac, + 0x0, 0xe, 0x2a, 0x70, 0x0, 0xe2, 0xa6, 0x0, + 0xe, 0x2a, 0x60, 0x0, 0xe2, 0x95, 0x0, 0xd, + 0x10, + + /* U+006F "o" */ + 0x0, 0x7e, 0xfb, 0x10, 0x7, 0xd3, 0x29, 0xd0, + 0xe, 0x20, 0x0, 0xc5, 0xf, 0x0, 0x0, 0x97, + 0xe, 0x20, 0x0, 0xc5, 0x8, 0xd3, 0x29, 0xd0, + 0x0, 0x8e, 0xfb, 0x20, + + /* U+0070 "p" */ + 0xa6, 0xcf, 0xc3, 0xb, 0xe4, 0x6, 0xe0, 0xb8, + 0x0, 0xc, 0x4b, 0x50, 0x0, 0xa6, 0xb8, 0x0, + 0xd, 0x4b, 0xf5, 0x28, 0xe0, 0xb7, 0xcf, 0xc3, + 0xb, 0x50, 0x0, 0x0, 0xb5, 0x0, 0x0, 0xa, + 0x40, 0x0, 0x0, + + /* U+0071 "q" */ + 0x0, 0x9f, 0xe6, 0xc0, 0x8, 0xb1, 0x1b, 0xf1, + 0xe, 0x20, 0x1, 0xf1, 0xf, 0x0, 0x0, 0xf1, + 0xe, 0x30, 0x2, 0xf1, 0x9, 0xc2, 0x3c, 0xf1, + 0x0, 0x9f, 0xe5, 0xf1, 0x0, 0x0, 0x0, 0xf1, + 0x0, 0x0, 0x0, 0xf1, 0x0, 0x0, 0x0, 0xd0, + + /* U+0072 "r" */ + 0xd0, 0x6d, 0xf4, 0xe7, 0xd6, 0x40, 0xed, 0x10, + 0x0, 0xe6, 0x0, 0x0, 0xe2, 0x0, 0x0, 0xe2, + 0x0, 0x0, 0xd1, 0x0, 0x0, + + /* U+0073 "s" */ + 0x1a, 0xee, 0xc5, 0x9, 0xa2, 0x26, 0x80, 0x9a, + 0x31, 0x0, 0x1, 0x9d, 0xfe, 0x60, 0x0, 0x0, + 0x3f, 0x18, 0x72, 0x15, 0xf1, 0x3a, 0xef, 0xd5, + 0x0, + + /* U+0074 "t" */ + 0x0, 0x59, 0x0, 0x0, 0x0, 0x6a, 0x0, 0x0, + 0x0, 0x6a, 0x0, 0x0, 0x2e, 0xff, 0xff, 0xc0, + 0x1, 0x7a, 0x22, 0x10, 0x0, 0x6a, 0x0, 0x0, + 0x0, 0x5a, 0x0, 0x0, 0x0, 0x3d, 0x23, 0x94, + 0x0, 0x9, 0xfe, 0x91, + + /* U+0075 "u" */ + 0xa3, 0x0, 0xe, 0xb, 0x40, 0x0, 0xf0, 0xb4, + 0x0, 0xf, 0xb, 0x40, 0x1, 0xf0, 0xb4, 0x0, + 0x6f, 0x9, 0x90, 0x5c, 0xf0, 0x1c, 0xfb, 0x1d, + 0x0, + + /* U+0076 "v" */ + 0x1d, 0x0, 0x0, 0x86, 0xc, 0x60, 0x0, 0xe2, + 0x5, 0xc0, 0x6, 0xb0, 0x0, 0xe3, 0xd, 0x40, + 0x0, 0x7a, 0x4d, 0x0, 0x0, 0x1f, 0xc7, 0x0, + 0x0, 0x9, 0xe1, 0x0, + + /* U+0077 "w" */ + 0x86, 0x0, 0x0, 0xd, 0x6a, 0x4, 0xa0, 0x4c, + 0x2d, 0xa, 0xf1, 0x78, 0xe, 0x1e, 0x95, 0xb4, + 0xb, 0x9a, 0x4a, 0xe1, 0x7, 0xf5, 0xe, 0xd0, + 0x3, 0xe1, 0x9, 0x90, + + /* U+0078 "x" */ + 0x97, 0x0, 0x1d, 0x12, 0xe4, 0xc, 0x80, 0x4, + 0xeb, 0xb0, 0x0, 0xb, 0xf3, 0x0, 0x5, 0xe9, + 0xc0, 0x3, 0xe3, 0xb, 0xa0, 0xb6, 0x0, 0x1d, + 0x30, + + /* U+0079 "y" */ + 0x1d, 0x0, 0x0, 0x86, 0xc, 0x60, 0x1, 0xf2, + 0x4, 0xd0, 0x7, 0xb0, 0x0, 0xd5, 0xe, 0x30, + 0x0, 0x6c, 0x6c, 0x0, 0x0, 0xe, 0xe5, 0x0, + 0x0, 0x8, 0xd0, 0x0, 0x0, 0xc, 0x60, 0x0, + 0x0, 0x3e, 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, + + /* U+007A "z" */ + 0x8f, 0xff, 0xff, 0x0, 0x11, 0x2e, 0x70, 0x0, + 0xb, 0xa0, 0x0, 0x8, 0xd0, 0x0, 0x5, 0xe2, + 0x0, 0x3, 0xf5, 0x11, 0x0, 0xbf, 0xff, 0xff, + 0x10, + + /* U+007B "{" */ + 0x0, 0x6, 0xca, 0x0, 0x3e, 0x41, 0x0, 0x78, + 0x0, 0x0, 0x87, 0x0, 0x0, 0x87, 0x0, 0x2, + 0xd2, 0x0, 0xaf, 0x50, 0x0, 0x14, 0xd2, 0x0, + 0x0, 0x88, 0x0, 0x0, 0x88, 0x0, 0x0, 0x88, + 0x0, 0x0, 0x5d, 0x10, 0x0, 0x9, 0xfa, 0x0, + 0x0, 0x0, + + /* U+007C "|" */ + 0x4a, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, + 0x5b, 0x5b, 0x5b, 0x5b, 0x4a, + + /* U+007D "}" */ + 0x4d, 0x91, 0x0, 0x0, 0x2a, 0x90, 0x0, 0x0, + 0x2e, 0x0, 0x0, 0x1, 0xe0, 0x0, 0x0, 0xf, + 0x0, 0x0, 0x0, 0xb6, 0x0, 0x0, 0x1, 0xdf, + 0x10, 0x0, 0xb7, 0x20, 0x0, 0x1e, 0x0, 0x0, + 0x1, 0xe0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x8, + 0xb0, 0x0, 0x4f, 0xd2, 0x0, 0x0, 0x10, 0x0, + 0x0, + + /* U+007E "~" */ + 0x4e, 0xd5, 0x7, 0x2a, 0x45, 0xdf, 0xc0, 0x0, + 0x0, 0x20, 0x0, + + /* U+00B0 "°" */ + 0x8, 0xfb, 0x3, 0xc1, 0xa6, 0x3c, 0x1a, 0x60, + 0x8f, 0xb0, + + /* U+2022 "•" */ + 0x29, 0xa5, 0x6f, 0xfc, 0x6f, 0xfc, 0x4e, 0xf9, + + /* U+E0B4 "" */ + 0x2, 0x40, 0x42, 0x0, 0x0, 0xaf, 0x1f, 0xa0, + 0x0, 0x7e, 0xfc, 0xfd, 0x20, 0xf, 0xff, 0xff, + 0xff, 0x30, 0xfc, 0x0, 0x5, 0xfa, 0xf, 0xc0, + 0x0, 0xe, 0xd0, 0xfc, 0x0, 0x5, 0xfb, 0xf, + 0xff, 0xff, 0xff, 0x80, 0xfe, 0xbb, 0xbb, 0xef, + 0x5f, 0xc0, 0x0, 0x2, 0xfa, 0xfc, 0x0, 0x0, + 0x2f, 0xaf, 0xfc, 0xcc, 0xcf, 0xf4, 0xbf, 0xff, + 0xff, 0xd5, 0x0, 0xaf, 0x1f, 0xa0, 0x0, 0x4, + 0x90, 0x94, 0x0, 0x0, + + /* U+F001 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x7b, 0xfb, 0x0, + 0x0, 0x0, 0x3, 0x8d, 0xff, 0xff, 0xd0, 0x0, + 0x2, 0xae, 0xff, 0xff, 0xff, 0xfd, 0x0, 0x0, + 0x9f, 0xff, 0xff, 0xff, 0xff, 0xd0, 0x0, 0xa, + 0xff, 0xff, 0xfa, 0x51, 0xed, 0x0, 0x0, 0xaf, + 0xd9, 0x40, 0x0, 0xe, 0xd0, 0x0, 0xa, 0xf1, + 0x0, 0x0, 0x0, 0xed, 0x0, 0x0, 0xaf, 0x10, + 0x0, 0x2, 0x3e, 0xd0, 0x0, 0xa, 0xf1, 0x0, + 0xa, 0xff, 0xfd, 0x0, 0x47, 0xcf, 0x10, 0x5, + 0xff, 0xff, 0xd0, 0xaf, 0xff, 0xf1, 0x0, 0x4f, + 0xff, 0xfa, 0x1f, 0xff, 0xff, 0x10, 0x0, 0x8f, + 0xfc, 0x10, 0xdf, 0xff, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xad, 0xa2, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+F008 "" */ + 0x1, 0x22, 0x22, 0x22, 0x22, 0x22, 0x10, 0x8f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xfc, 0x9f, + 0xe9, 0x99, 0x9e, 0xf9, 0xcf, 0xf5, 0xf, 0x60, + 0x0, 0x6, 0xf0, 0x5f, 0xff, 0xef, 0x60, 0x0, + 0x6, 0xfe, 0xff, 0xff, 0xef, 0xa2, 0x22, 0x2a, + 0xfe, 0xff, 0xf5, 0xf, 0xff, 0xff, 0xff, 0xf0, + 0x5f, 0xf7, 0x3f, 0xfd, 0xdd, 0xdf, 0xf3, 0x7f, + 0xff, 0xff, 0x70, 0x0, 0x7, 0xff, 0xff, 0xfc, + 0x9f, 0x60, 0x0, 0x6, 0xf9, 0xcf, 0xf5, 0xf, + 0x70, 0x0, 0x7, 0xf0, 0x5f, 0xee, 0xdf, 0xfc, + 0xcc, 0xcf, 0xfd, 0xee, 0x5e, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe5, + + /* U+F00B "" */ + 0x1, 0x22, 0x22, 0x22, 0x22, 0x22, 0x10, 0x8f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xfe, 0x9d, + 0xfa, 0x99, 0x99, 0x99, 0xef, 0xfc, 0xa, 0xf1, + 0x0, 0x0, 0x0, 0xcf, 0xff, 0xce, 0xfd, 0xcc, + 0xcc, 0xcc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfc, 0xa, 0xf1, 0x0, 0x0, 0x0, + 0xcf, 0xfe, 0x9d, 0xfa, 0x99, 0x99, 0x99, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0x2b, 0xf3, 0x22, 0x22, 0x22, 0xcf, 0xfc, 0xa, + 0xf1, 0x0, 0x0, 0x0, 0xcf, 0xef, 0xce, 0xfd, + 0xcc, 0xcc, 0xcc, 0xfe, 0x5e, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe5, + + /* U+F00C "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4f, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xff, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x4f, 0xf4, 0x0, 0xf, 0xb0, 0x0, 0x4, + 0xff, 0x40, 0x0, 0xb, 0xfb, 0x0, 0x4f, 0xf4, + 0x0, 0x0, 0x0, 0xbf, 0xb4, 0xff, 0x40, 0x0, + 0x0, 0x0, 0xb, 0xff, 0xf4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbf, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F00D "" */ + 0x10, 0x0, 0x0, 0x1, 0xe, 0xd1, 0x0, 0x3, + 0xfa, 0x9f, 0xd1, 0x3, 0xff, 0x50, 0xaf, 0xc3, + 0xef, 0x60, 0x0, 0xaf, 0xff, 0x70, 0x0, 0x2, + 0xff, 0xd0, 0x0, 0x1, 0xdf, 0xef, 0xa0, 0x1, + 0xdf, 0x90, 0xcf, 0xa0, 0xbf, 0xa0, 0x1, 0xdf, + 0x7c, 0xa0, 0x0, 0x1, 0xd8, + + /* U+F011 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xcb, 0x0, 0x0, 0x0, 0x0, 0x39, + 0x0, 0xed, 0x1, 0x92, 0x0, 0x2, 0xff, 0x20, + 0xed, 0x2, 0xfe, 0x10, 0xc, 0xf5, 0x0, 0xed, + 0x0, 0x6f, 0xb0, 0x3f, 0xb0, 0x0, 0xed, 0x0, + 0xc, 0xf2, 0x7f, 0x50, 0x0, 0xed, 0x0, 0x6, + 0xf6, 0x8f, 0x30, 0x0, 0xed, 0x0, 0x4, 0xf7, + 0x6f, 0x40, 0x0, 0x76, 0x0, 0x5, 0xf5, 0x3f, + 0x90, 0x0, 0x0, 0x0, 0xa, 0xf2, 0xd, 0xf3, + 0x0, 0x0, 0x0, 0x4f, 0xc0, 0x3, 0xfe, 0x50, + 0x0, 0x6, 0xff, 0x20, 0x0, 0x5f, 0xfd, 0xaa, + 0xef, 0xe4, 0x0, 0x0, 0x2, 0x9e, 0xff, 0xe8, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, + 0x0, + + /* U+F013 "" */ + 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0xff, 0xe0, 0x0, 0x0, 0x6, 0xb6, 0xbf, + 0xff, 0xfb, 0x6b, 0x60, 0x2f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf2, 0x8f, 0xff, 0xff, 0xcc, 0xff, + 0xff, 0xf8, 0x1c, 0xff, 0xf5, 0x0, 0x5f, 0xff, + 0xc1, 0x3, 0xff, 0xe0, 0x0, 0xe, 0xff, 0x30, + 0x5, 0xff, 0xf0, 0x0, 0xf, 0xff, 0x50, 0x4f, + 0xff, 0xfa, 0x22, 0xaf, 0xff, 0xf4, 0x6f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf6, 0xd, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xd0, 0x2, 0x40, 0x4f, 0xff, + 0xf4, 0x4, 0x20, 0x0, 0x0, 0xd, 0xff, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x5, 0xbb, 0x50, 0x0, + 0x0, + + /* U+F015 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3e, 0xc1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xff, 0xfd, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0xff, 0xff, 0xe3, 0x0, 0x0, + 0x0, 0x8, 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, + 0x0, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x0, + 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x9d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd6, + 0x4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x4, 0xff, 0xff, 0xc9, 0x9e, 0xff, 0xff, 0x0, + 0x4, 0xff, 0xff, 0x20, 0x6, 0xff, 0xff, 0x0, + 0x4, 0xff, 0xff, 0x20, 0x6, 0xff, 0xff, 0x0, + 0x3, 0xff, 0xff, 0x10, 0x5, 0xff, 0xff, 0x0, + 0x1, 0xdf, 0xfc, 0x0, 0x2, 0xef, 0xfa, 0x0, + + /* U+F019 "" */ + 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xdd, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xdd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdd, 0x0, + 0x0, 0x0, 0x0, 0x3f, 0x70, 0xdd, 0x7, 0xf3, + 0x0, 0x0, 0x1e, 0xf7, 0xdd, 0x7f, 0xe1, 0x0, + 0x0, 0x2, 0xef, 0xff, 0xfe, 0x20, 0x0, 0x0, + 0x0, 0x2e, 0xff, 0xe2, 0x0, 0x0, 0x2a, 0xbb, + 0x92, 0xee, 0x29, 0xbb, 0xa2, 0xdf, 0xff, 0xfb, + 0x11, 0xbf, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf4, 0xaf, 0xdf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0x29, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x92, + + /* U+F01C "" */ + 0x0, 0x59, 0x99, 0x99, 0x99, 0x95, 0x0, 0x4, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0x9, 0xf5, + 0x22, 0x22, 0x22, 0x5f, 0x90, 0xc, 0xf0, 0x0, + 0x0, 0x0, 0xf, 0xc0, 0xf, 0xc0, 0x0, 0x0, + 0x0, 0xc, 0xf1, 0x4f, 0x80, 0x0, 0x0, 0x0, + 0x8, 0xf4, 0x8f, 0x40, 0x0, 0x0, 0x0, 0x4, + 0xf8, 0xcf, 0x53, 0x0, 0x0, 0x0, 0x35, 0xfc, + 0xff, 0xff, 0x50, 0x0, 0x5, 0xff, 0xff, 0xff, + 0xff, 0xe9, 0x88, 0x9e, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x5e, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe5, + + /* U+F021 "" */ + 0x0, 0x0, 0x1, 0x33, 0x10, 0x0, 0x20, 0x0, + 0x1, 0xaf, 0xff, 0xfc, 0x30, 0xf9, 0x0, 0x3e, + 0xfc, 0x87, 0xbf, 0xf7, 0xfa, 0x1, 0xef, 0x50, + 0x0, 0x3, 0xef, 0xfa, 0x8, 0xf7, 0x0, 0x0, + 0x4c, 0xef, 0xfa, 0x7, 0xc0, 0x0, 0x0, 0x5e, + 0xff, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x39, 0x99, 0x92, 0x0, 0x0, 0x6, 0x30, + 0xaf, 0xff, 0xf7, 0x0, 0x0, 0x3f, 0x90, 0xaf, + 0xfc, 0x20, 0x0, 0x1, 0xdf, 0x30, 0xaf, 0xcf, + 0xd5, 0x22, 0x6e, 0xf7, 0x0, 0xaf, 0x19, 0xff, + 0xff, 0xff, 0x60, 0x0, 0x37, 0x0, 0x27, 0x99, + 0x61, 0x0, 0x0, + + /* U+F026 "" */ + 0x0, 0x0, 0x0, 0x5, 0x30, 0x0, 0x0, 0x8, + 0xfb, 0x0, 0x0, 0xa, 0xff, 0xb0, 0x0, 0xb, + 0xff, 0xfb, 0x6e, 0xff, 0xff, 0xff, 0xbe, 0xff, + 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xbf, + 0xff, 0xff, 0xff, 0xfb, 0x9f, 0xff, 0xff, 0xff, + 0xb0, 0x34, 0x5e, 0xff, 0xfb, 0x0, 0x0, 0x2d, + 0xff, 0xb0, 0x0, 0x0, 0x1c, 0xfb, 0x0, 0x0, + 0x0, 0x9, 0x60, + + /* U+F027 "" */ + 0x0, 0x0, 0x0, 0x5, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x8, 0xfb, 0x0, 0x0, 0x0, 0x0, 0xa, + 0xff, 0xc0, 0x0, 0x0, 0x0, 0xb, 0xff, 0xfc, + 0x0, 0x0, 0x6e, 0xff, 0xff, 0xff, 0xc0, 0x32, + 0xe, 0xff, 0xff, 0xff, 0xfc, 0xa, 0xd0, 0xff, + 0xff, 0xff, 0xff, 0xc0, 0x2f, 0x2f, 0xff, 0xff, + 0xff, 0xfc, 0x5, 0xf1, 0x9f, 0xff, 0xff, 0xff, + 0xc0, 0x97, 0x0, 0x34, 0x5e, 0xff, 0xfc, 0x0, + 0x0, 0x0, 0x0, 0x2d, 0xff, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0xfb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0x60, 0x0, 0x0, + + /* U+F028 "" */ + 0x0, 0x0, 0x0, 0x5, 0x30, 0x0, 0x2, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x8f, 0xb0, 0x0, 0x4, + 0xf6, 0x0, 0x0, 0x0, 0xa, 0xff, 0xc0, 0x0, + 0x60, 0x6f, 0x30, 0x0, 0x0, 0xbf, 0xff, 0xc0, + 0x0, 0xeb, 0xb, 0xc0, 0x6e, 0xff, 0xff, 0xff, + 0xc0, 0x32, 0x3f, 0x53, 0xf2, 0xef, 0xff, 0xff, + 0xff, 0xc0, 0xad, 0xa, 0xb0, 0xf5, 0xff, 0xff, + 0xff, 0xff, 0xc0, 0x2f, 0x27, 0xd0, 0xd7, 0xff, + 0xff, 0xff, 0xff, 0xc0, 0x5f, 0x18, 0xc0, 0xe6, + 0x9f, 0xff, 0xff, 0xff, 0xc0, 0x97, 0xd, 0x81, + 0xf4, 0x3, 0x45, 0xef, 0xff, 0xc0, 0x0, 0x9f, + 0x17, 0xe0, 0x0, 0x0, 0x2d, 0xff, 0xc0, 0x0, + 0xd4, 0x1e, 0x80, 0x0, 0x0, 0x1, 0xcf, 0xb0, + 0x0, 0x1, 0xdd, 0x0, 0x0, 0x0, 0x0, 0x9, + 0x60, 0x0, 0x5, 0xd1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F03E "" */ + 0x1, 0x22, 0x22, 0x22, 0x22, 0x22, 0x10, 0x8f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xcb, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x0, 0xbf, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x21, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x5f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0x7, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x60, 0x0, 0xbf, 0xff, + 0xff, 0xf4, 0x19, 0x0, 0x0, 0x1e, 0xff, 0xff, + 0x70, 0x0, 0x0, 0x0, 0x5, 0xff, 0xfd, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xdf, 0xef, 0xdc, 0xcc, + 0xcc, 0xcc, 0xcd, 0xfe, 0x5e, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe5, + + /* U+F043 "" */ + 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0xa, + 0xf3, 0x0, 0x0, 0x0, 0x5, 0xff, 0xd0, 0x0, + 0x0, 0x1, 0xef, 0xff, 0x70, 0x0, 0x0, 0x8f, + 0xff, 0xff, 0x10, 0x0, 0x2f, 0xff, 0xff, 0xf9, + 0x0, 0xa, 0xff, 0xff, 0xff, 0xf2, 0x1, 0xff, + 0xff, 0xff, 0xff, 0x90, 0x6f, 0xff, 0xff, 0xff, + 0xfe, 0x8, 0xf4, 0xef, 0xff, 0xff, 0xf0, 0x6f, + 0x79, 0xff, 0xff, 0xfe, 0x1, 0xff, 0x35, 0xbf, + 0xff, 0x80, 0x5, 0xff, 0xbc, 0xff, 0xc0, 0x0, + 0x4, 0xdf, 0xff, 0x90, 0x0, 0x0, 0x0, 0x12, + 0x0, 0x0, 0x0, + + /* U+F048 "" */ + 0x42, 0x0, 0x0, 0x5, 0x3f, 0xb0, 0x0, 0x9, + 0xfb, 0xfb, 0x0, 0x1c, 0xff, 0xbf, 0xb0, 0x2d, + 0xff, 0xfb, 0xfb, 0x4f, 0xff, 0xff, 0xbf, 0xff, + 0xff, 0xff, 0xfb, 0xfd, 0xcf, 0xff, 0xff, 0xbf, + 0xb0, 0x9f, 0xff, 0xfb, 0xfb, 0x0, 0x7f, 0xff, + 0xbf, 0xb0, 0x0, 0x4f, 0xfb, 0xc8, 0x0, 0x0, + 0x2d, 0x90, 0x0, 0x0, 0x0, 0x0, + + /* U+F04B "" */ + 0x14, 0x0, 0x0, 0x0, 0x0, 0xd, 0xfd, 0x40, + 0x0, 0x0, 0x0, 0xff, 0xff, 0xa1, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xf6, 0x0, 0x0, 0xff, 0xff, + 0xff, 0xfc, 0x30, 0xf, 0xff, 0xff, 0xff, 0xff, + 0x90, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xff, + 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, + 0xb2, 0xf, 0xff, 0xff, 0xfe, 0x50, 0x0, 0xff, + 0xff, 0xf8, 0x0, 0x0, 0xf, 0xff, 0xc2, 0x0, + 0x0, 0x0, 0x7c, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F04C "" */ + 0x37, 0x60, 0x2, 0x76, 0xe, 0xff, 0x60, 0xdf, + 0xf7, 0xff, 0xf7, 0xe, 0xff, 0x9f, 0xff, 0x70, + 0xef, 0xf9, 0xff, 0xf7, 0xe, 0xff, 0x9f, 0xff, + 0x70, 0xef, 0xf9, 0xff, 0xf7, 0xe, 0xff, 0x9f, + 0xff, 0x70, 0xef, 0xf9, 0xff, 0xf7, 0xe, 0xff, + 0x9f, 0xff, 0x70, 0xef, 0xf9, 0x9f, 0xe3, 0x8, + 0xfe, 0x30, + + /* U+F04D "" */ + 0x17, 0x88, 0x88, 0x88, 0x74, 0xc, 0xff, 0xff, + 0xff, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, + 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x6f, + 0xff, 0xff, 0xff, 0xfc, 0x10, + + /* U+F051 "" */ + 0x53, 0x0, 0x0, 0x4, 0x2f, 0xf7, 0x0, 0x0, + 0xfb, 0xff, 0xf9, 0x0, 0xf, 0xcf, 0xff, 0xfc, + 0x10, 0xfc, 0xff, 0xff, 0xfd, 0x2f, 0xcf, 0xff, + 0xff, 0xfe, 0xfc, 0xff, 0xff, 0xff, 0x9f, 0xcf, + 0xff, 0xff, 0x70, 0xfc, 0xff, 0xff, 0x40, 0xf, + 0xcf, 0xfd, 0x20, 0x0, 0xfc, 0xcb, 0x10, 0x0, + 0xc, 0x80, 0x0, 0x0, 0x0, 0x0, + + /* U+F052 "" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0xef, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0xff, 0xf3, 0x0, 0x0, 0x0, 0x1, 0xdf, + 0xff, 0xfe, 0x20, 0x0, 0x0, 0xc, 0xff, 0xff, + 0xff, 0xe2, 0x0, 0x0, 0xbf, 0xff, 0xff, 0xff, + 0xfd, 0x10, 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xc0, 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x5, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0x70, 0xe, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf3, 0x9, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xc0, + + /* U+F053 "" */ + 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x4, 0xfc, + 0x0, 0x0, 0x4f, 0xf4, 0x0, 0x4, 0xff, 0x40, + 0x0, 0x4f, 0xf4, 0x0, 0x4, 0xff, 0x40, 0x0, + 0xf, 0xf4, 0x0, 0x0, 0xb, 0xfb, 0x0, 0x0, + 0x0, 0xbf, 0xb0, 0x0, 0x0, 0xb, 0xfb, 0x0, + 0x0, 0x0, 0xbf, 0xb0, 0x0, 0x0, 0xb, 0xfa, + 0x0, 0x0, 0x0, 0xa8, + + /* U+F054 "" */ + 0x4, 0x0, 0x0, 0x0, 0x4f, 0xb0, 0x0, 0x0, + 0xb, 0xfb, 0x0, 0x0, 0x0, 0xbf, 0xb0, 0x0, + 0x0, 0xb, 0xfb, 0x0, 0x0, 0x0, 0xbf, 0xb0, + 0x0, 0x0, 0xc, 0xf7, 0x0, 0x0, 0x4f, 0xf3, + 0x0, 0x4, 0xff, 0x40, 0x0, 0x4f, 0xf4, 0x0, + 0x4, 0xff, 0x40, 0x0, 0x2f, 0xf4, 0x0, 0x0, + 0x2c, 0x40, 0x0, 0x0, + + /* U+F067 "" */ + 0x0, 0x0, 0x8, 0xc0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0xb, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xf0, 0x0, 0x0, 0x5f, 0xff, + 0xff, 0xff, 0xff, 0xf9, 0x4d, 0xdd, 0xdf, 0xfd, + 0xdd, 0xd7, 0x0, 0x0, 0xb, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xc0, 0x0, 0x0, + + /* U+F068 "" */ + 0x4d, 0xdd, 0xdd, 0xdd, 0xdd, 0xd7, 0x5f, 0xff, + 0xff, 0xff, 0xff, 0xf9, + + /* U+F06E "" */ + 0x0, 0x0, 0x0, 0x3, 0x54, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7e, 0xff, 0xff, 0xd5, 0x0, + 0x0, 0x0, 0x2, 0xdf, 0xff, 0xde, 0xff, 0xfa, + 0x0, 0x0, 0x1, 0xef, 0xfa, 0x10, 0x3, 0xcf, + 0xfb, 0x0, 0x0, 0xcf, 0xfa, 0x0, 0x3a, 0x20, + 0xdf, 0xf9, 0x0, 0x7f, 0xff, 0x20, 0x3, 0xff, + 0x16, 0xff, 0xf3, 0xe, 0xff, 0xf0, 0x33, 0xcf, + 0xf6, 0x3f, 0xff, 0xa0, 0xbf, 0xff, 0x9, 0xff, + 0xff, 0x54, 0xff, 0xf7, 0x2, 0xff, 0xf6, 0x2e, + 0xff, 0xd0, 0x9f, 0xfd, 0x0, 0x7, 0xff, 0xe2, + 0x16, 0x50, 0x5f, 0xff, 0x30, 0x0, 0x8, 0xff, + 0xf9, 0x56, 0xbf, 0xff, 0x50, 0x0, 0x0, 0x5, + 0xef, 0xff, 0xff, 0xfd, 0x30, 0x0, 0x0, 0x0, + 0x1, 0x6b, 0xdc, 0xa5, 0x0, 0x0, 0x0, + + /* U+F070 "" */ + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xeb, 0x10, 0x0, 0x3, 0x54, 0x10, + 0x0, 0x0, 0x0, 0x2, 0xde, 0x31, 0x8f, 0xff, + 0xff, 0xc4, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xef, + 0xff, 0xee, 0xff, 0xf9, 0x0, 0x0, 0x0, 0x0, + 0x7f, 0xfa, 0x10, 0x4, 0xdf, 0xfa, 0x0, 0x0, + 0x0, 0x80, 0x4e, 0xc1, 0x4b, 0x21, 0xff, 0xf7, + 0x0, 0x0, 0x8f, 0xc1, 0x2c, 0xe9, 0xfe, 0x18, + 0xff, 0xf1, 0x0, 0xf, 0xff, 0xc0, 0x9, 0xff, + 0xf4, 0x5f, 0xff, 0x80, 0x0, 0xdf, 0xfe, 0x0, + 0x6, 0xff, 0x36, 0xff, 0xf5, 0x0, 0x4, 0xff, + 0xf4, 0x0, 0x3, 0xed, 0xcf, 0xfc, 0x0, 0x0, + 0x9, 0xff, 0xd1, 0x0, 0x1, 0xbf, 0xfe, 0x10, + 0x0, 0x0, 0xa, 0xff, 0xe8, 0x56, 0x50, 0x8f, + 0xb0, 0x0, 0x0, 0x0, 0x7, 0xff, 0xff, 0xff, + 0x80, 0x5f, 0xc1, 0x0, 0x0, 0x0, 0x1, 0x7b, + 0xdc, 0xa4, 0x0, 0x2d, 0xe2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x40, + + /* U+F071 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1e, 0xe1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x9f, 0xf9, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xff, 0xff, 0x30, 0x0, 0x0, + 0x0, 0x0, 0xc, 0xfa, 0xaf, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0xf5, 0x5f, 0xf6, 0x0, 0x0, + 0x0, 0x1, 0xef, 0xf5, 0x5f, 0xfe, 0x10, 0x0, + 0x0, 0x9, 0xff, 0xf5, 0x5f, 0xff, 0x90, 0x0, + 0x0, 0x2f, 0xff, 0xfa, 0xaf, 0xff, 0xf3, 0x0, + 0x0, 0xcf, 0xff, 0xfc, 0xcf, 0xff, 0xfc, 0x0, + 0x5, 0xff, 0xff, 0xf3, 0x3f, 0xff, 0xff, 0x50, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0xa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, + + /* U+F074 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7f, 0x90, 0x6a, 0x96, + 0x0, 0x0, 0x49, 0xdf, 0xf9, 0xdf, 0xff, 0xb0, + 0x8, 0xff, 0xff, 0xfd, 0x2, 0x2a, 0xf8, 0x2f, + 0xd2, 0x9f, 0xe3, 0x0, 0x0, 0xdf, 0x49, 0x30, + 0x4c, 0x30, 0x0, 0x0, 0x2f, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x36, 0xfc, 0x0, 0x4, 0x0, + 0x0, 0x4, 0xf4, 0xaf, 0x80, 0x7f, 0x90, 0x6a, + 0xaf, 0xf3, 0xd, 0xfa, 0xdf, 0xf9, 0xdf, 0xfe, + 0x40, 0x2, 0xcf, 0xff, 0xfd, 0x2, 0x10, 0x0, + 0x0, 0x1, 0x9f, 0xe3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4c, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+F077 "" */ + 0x0, 0x0, 0x0, 0x66, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x7f, 0xdd, 0xf8, 0x0, 0x0, 0x0, 0x7, 0xfd, + 0x11, 0xdf, 0x80, 0x0, 0x0, 0x7f, 0xd1, 0x0, + 0x1d, 0xf8, 0x0, 0x7, 0xfd, 0x10, 0x0, 0x1, + 0xdf, 0x70, 0xf, 0xd1, 0x0, 0x0, 0x0, 0x2e, + 0xf0, 0x3, 0x10, 0x0, 0x0, 0x0, 0x1, 0x30, + + /* U+F078 "" */ + 0xb, 0x70, 0x0, 0x0, 0x0, 0x7, 0xb0, 0xd, + 0xf7, 0x0, 0x0, 0x0, 0x7f, 0xd0, 0x2, 0xef, + 0x70, 0x0, 0x7, 0xfe, 0x10, 0x0, 0x2e, 0xf7, + 0x0, 0x7f, 0xe1, 0x0, 0x0, 0x2, 0xef, 0x77, + 0xfe, 0x10, 0x0, 0x0, 0x0, 0x2e, 0xff, 0xe1, + 0x0, 0x0, 0x0, 0x0, 0x2, 0xdd, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F079 "" */ + 0x0, 0x63, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa, 0xff, 0x40, 0x2, 0xab, 0xba, 0x70, 0x0, + 0x9f, 0xff, 0xf3, 0x4, 0xff, 0xff, 0xfa, 0x0, + 0x8e, 0xff, 0xe3, 0x0, 0x0, 0x1, 0xdf, 0x0, + 0x1, 0xfa, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x10, + 0x1, 0xfa, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x10, + 0x1, 0xfa, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x10, + 0x0, 0xfb, 0x0, 0x0, 0x0, 0x18, 0xdf, 0x95, + 0x0, 0xcf, 0xcb, 0xba, 0x20, 0x4f, 0xff, 0xfc, + 0x0, 0x2c, 0xff, 0xff, 0x40, 0x9, 0xff, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8c, 0x20, + + /* U+F07B "" */ + 0x3, 0x44, 0x42, 0x0, 0x0, 0x0, 0x0, 0xaf, + 0xff, 0xff, 0x70, 0x0, 0x0, 0x0, 0xff, 0xff, + 0xff, 0xfb, 0x88, 0x88, 0x71, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x5e, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe5, + + /* U+F093 "" */ + 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x3f, 0xff, 0xf3, 0x0, 0x0, 0x0, 0x3, 0xff, + 0xff, 0xff, 0x30, 0x0, 0x0, 0x2f, 0xf4, 0xee, + 0x4f, 0xf2, 0x0, 0x0, 0x2d, 0x40, 0xee, 0x4, + 0xd2, 0x0, 0x0, 0x0, 0x0, 0xee, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xee, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xee, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xee, 0x0, 0x0, 0x0, 0x2a, 0xbb, + 0xb3, 0xcc, 0x3b, 0xbb, 0xa2, 0xdf, 0xff, 0xfc, + 0x22, 0xcf, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf4, 0xaf, 0xdf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0x29, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x92, + + /* U+F095 "" */ + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xcf, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, + 0xff, 0xe0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, + 0xff, 0x50, 0x0, 0x0, 0x0, 0x0, 0xdf, 0xff, + 0xf9, 0x0, 0x0, 0x0, 0x0, 0x9, 0xff, 0xfd, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xff, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xf9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6, 0xff, 0xf5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, 0xf5, 0x0, + 0x8d, 0x81, 0x0, 0x0, 0x1e, 0xff, 0xfa, 0x7f, + 0xff, 0xf9, 0x0, 0x0, 0x2d, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x0, 0x0, 0x1a, 0xff, 0xff, 0xff, + 0xfb, 0x0, 0x0, 0x0, 0x4, 0xcf, 0xff, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x26, 0x9b, 0xa0, + 0x0, + + /* U+F0C4 "" */ + 0x0, 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0xff, 0xc1, 0x0, 0x0, 0x2, 0x40, 0x9f, 0xcb, + 0xfb, 0x0, 0x0, 0x6f, 0xfa, 0xed, 0x0, 0xbf, + 0x0, 0x7, 0xff, 0xe2, 0xde, 0x10, 0xdf, 0x0, + 0x7f, 0xfe, 0x20, 0x6f, 0xff, 0xff, 0x77, 0xff, + 0xe2, 0x0, 0x6, 0xcc, 0xef, 0xff, 0xfe, 0x20, + 0x0, 0x0, 0x0, 0x2f, 0xff, 0xe2, 0x0, 0x0, + 0x0, 0x11, 0x5f, 0xfe, 0x23, 0x0, 0x0, 0xa, + 0xff, 0xff, 0xe2, 0x9f, 0x50, 0x0, 0xaf, 0xcb, + 0xff, 0x22, 0xef, 0xf6, 0x0, 0xed, 0x0, 0xbf, + 0x10, 0x2e, 0xff, 0x60, 0xdf, 0x22, 0xdf, 0x0, + 0x2, 0xef, 0xf6, 0x5f, 0xff, 0xf7, 0x0, 0x0, + 0x1b, 0xd6, 0x4, 0xaa, 0x50, 0x0, 0x0, 0x0, + 0x0, + + /* U+F0C5 "" */ + 0x0, 0x0, 0x0, 0x11, 0x11, 0x11, 0x0, 0x0, + 0x0, 0x2e, 0xff, 0xff, 0xff, 0xf7, 0x0, 0x0, + 0x9f, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x9f, + 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x9f, 0xff, + 0xff, 0xff, 0xff, 0x2a, 0xb5, 0x9f, 0xff, 0xff, + 0xff, 0xff, 0xdf, 0xf7, 0x9f, 0xff, 0xff, 0xff, + 0xff, 0xfc, 0x0, 0x9f, 0xff, 0xff, 0xff, 0xff, + 0xfb, 0x0, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0x0, 0x6f, 0xff, 0xff, 0xff, 0xfc, 0xfb, 0x0, + 0x5, 0x88, 0x88, 0x88, 0x71, 0xfb, 0x0, 0x0, + 0x1, 0xb7, 0x0, 0x0, 0xfb, 0x0, 0x0, 0x1, + 0xf9, 0x0, 0x0, 0xef, 0xff, 0xff, 0xff, 0xf7, + 0x0, 0x0, 0x3b, 0xbb, 0xbb, 0xbb, 0x90, 0x0, + 0x0, + + /* U+F0C7 "" */ + 0x1, 0x22, 0x22, 0x22, 0x10, 0x0, 0x8, 0xff, + 0xff, 0xff, 0xff, 0xb0, 0x0, 0xff, 0xa9, 0x99, + 0x99, 0xdf, 0xb0, 0xf, 0xc0, 0x0, 0x0, 0x4, + 0xff, 0xb0, 0xfb, 0x0, 0x0, 0x0, 0x3f, 0xff, + 0x3f, 0xe1, 0x0, 0x0, 0x7, 0xff, 0xf3, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, + 0xdc, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xb0, 0x7, + 0xff, 0xff, 0x3f, 0xff, 0xf6, 0x0, 0x2f, 0xff, + 0xf3, 0xff, 0xff, 0xc0, 0x8, 0xff, 0xff, 0x3e, + 0xff, 0xff, 0xee, 0xff, 0xff, 0xf2, 0x5e, 0xff, + 0xff, 0xff, 0xff, 0xe8, 0x0, + + /* U+F0C9 "" */ + 0x7b, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0xd, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x7b, + 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xa0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x10, + + /* U+F0E0 "" */ + 0x37, 0x77, 0x77, 0x77, 0x77, 0x77, 0x73, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xbf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfb, 0x29, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x92, 0xe5, 0x5f, 0xff, 0xff, + 0xff, 0xf5, 0x5e, 0xff, 0x92, 0xcf, 0xff, 0xfc, + 0x29, 0xff, 0xff, 0xfc, 0x29, 0xff, 0x92, 0xcf, + 0xff, 0xff, 0xff, 0xf5, 0x44, 0x5f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf6, + + /* U+F0E7 "" */ + 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x9f, + 0xf5, 0x0, 0x0, 0x0, 0xa, 0xff, 0xe0, 0x0, + 0x0, 0x1, 0xcf, 0xff, 0x70, 0x0, 0x0, 0x2d, + 0xff, 0xff, 0x10, 0x0, 0x3, 0xef, 0xff, 0xfb, + 0x11, 0x10, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf4, + 0x8, 0x99, 0xbf, 0xff, 0xff, 0xd1, 0x0, 0x0, + 0x9f, 0xff, 0xfc, 0x10, 0x0, 0x0, 0xff, 0xff, + 0xa0, 0x0, 0x0, 0x6, 0xff, 0xf8, 0x0, 0x0, + 0x0, 0xd, 0xff, 0x60, 0x0, 0x0, 0x0, 0x3f, + 0xf4, 0x0, 0x0, 0x0, 0x0, 0x1a, 0x30, 0x0, + 0x0, 0x0, + + /* U+F0EA "" */ + 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x2d, 0xf9, 0x21, 0x0, 0x0, 0x0, 0xbf, 0xfd, + 0x3f, 0xff, 0x70, 0x0, 0x0, 0xff, 0xff, 0xcf, + 0xd9, 0x70, 0x0, 0x0, 0xff, 0xff, 0xfb, 0x28, + 0x88, 0x42, 0x0, 0xff, 0xff, 0xf4, 0xcf, 0xff, + 0x79, 0x60, 0xff, 0xff, 0xf3, 0xdf, 0xff, 0x79, + 0xf6, 0xff, 0xff, 0xf3, 0xdf, 0xff, 0xb1, 0x11, + 0xff, 0xff, 0xf3, 0xdf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf3, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf3, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0xdf, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xf3, 0xdf, + 0xff, 0xff, 0xff, 0x3, 0x33, 0x30, 0xdf, 0xff, + 0xff, 0xff, 0x0, 0x0, 0x0, 0x7e, 0xff, 0xff, + 0xf9, + + /* U+F0F3 "" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xae, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x18, 0xff, 0xa3, 0x0, 0x0, 0x0, 0x2, 0xef, + 0xff, 0xff, 0x50, 0x0, 0x0, 0xb, 0xff, 0xff, + 0xff, 0xe1, 0x0, 0x0, 0x1f, 0xff, 0xff, 0xff, + 0xf5, 0x0, 0x0, 0x3f, 0xff, 0xff, 0xff, 0xf7, + 0x0, 0x0, 0x4f, 0xff, 0xff, 0xff, 0xf9, 0x0, + 0x0, 0x7f, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x0, + 0xef, 0xff, 0xff, 0xff, 0xff, 0x30, 0x9, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xd0, 0xd, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf2, 0x0, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x10, 0x0, 0x0, 0x7, 0xff, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9a, 0x20, 0x0, + 0x0, + + /* U+F11C "" */ + 0x2a, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x91, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, + 0xfc, 0xb, 0x50, 0xe1, 0x4b, 0xb, 0x51, 0xfb, + 0xfc, 0xb, 0x40, 0xe0, 0x4b, 0xb, 0x40, 0xfb, + 0xff, 0xef, 0xfe, 0xfe, 0xff, 0xef, 0xfe, 0xfb, + 0xfc, 0xa, 0x40, 0xe0, 0x3b, 0xa, 0x40, 0xfb, + 0xfd, 0x2c, 0x62, 0xe3, 0x6c, 0x2c, 0x63, 0xfb, + 0xff, 0xbf, 0xdb, 0xbb, 0xbb, 0xbf, 0xdc, 0xfb, + 0xfc, 0xa, 0x30, 0x0, 0x0, 0xa, 0x30, 0xfb, + 0xef, 0xcf, 0xdb, 0xbb, 0xbb, 0xcf, 0xdc, 0xfa, + 0x6e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd3, + + /* U+F124 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x16, 0xd9, 0x0, 0x0, 0x0, 0x39, + 0xff, 0xfa, 0x0, 0x0, 0x6c, 0xff, 0xff, 0xf4, + 0x2, 0x9f, 0xff, 0xff, 0xff, 0xd0, 0x5f, 0xff, + 0xff, 0xff, 0xff, 0x70, 0x3b, 0xbb, 0xbb, 0xff, + 0xff, 0x10, 0x0, 0x0, 0x0, 0xdf, 0xf9, 0x0, + 0x0, 0x0, 0x0, 0xdf, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0xdf, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xdf, + 0x60, 0x0, 0x0, 0x0, 0x0, 0xdf, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, + + /* U+F158 "" */ + 0x1, 0xef, 0xff, 0xfe, 0x70, 0x0, 0x3f, 0xed, + 0xdd, 0xff, 0xa0, 0x3, 0xf7, 0x0, 0x1, 0xdf, + 0x30, 0x3f, 0x70, 0x0, 0x5, 0xf7, 0x3, 0xf7, + 0x0, 0x0, 0x5f, 0x70, 0x3f, 0x70, 0x0, 0x1d, + 0xf3, 0x9e, 0xfe, 0xdd, 0xdf, 0xfa, 0xc, 0xff, + 0xff, 0xff, 0xe7, 0x0, 0x3, 0xf7, 0x0, 0x0, + 0x0, 0x9, 0xef, 0xed, 0xdd, 0xd6, 0x0, 0xcf, + 0xff, 0xff, 0xff, 0x80, 0x0, 0x3f, 0x70, 0x0, + 0x0, 0x0, 0x1, 0xe4, 0x0, 0x0, 0x0, 0x0, + + /* U+F1EB "" */ + 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x6b, 0xff, 0xff, 0xfd, 0x83, + 0x0, 0x0, 0x0, 0x7e, 0xff, 0xdb, 0x9a, 0xbf, + 0xff, 0xb3, 0x0, 0x2c, 0xfe, 0x71, 0x0, 0x0, + 0x0, 0x4b, 0xff, 0x70, 0xef, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3d, 0xf6, 0x54, 0x0, 0x4, + 0xae, 0xfe, 0xc7, 0x10, 0x0, 0x71, 0x0, 0x1, + 0xbf, 0xfe, 0xcd, 0xff, 0xf5, 0x0, 0x0, 0x0, + 0xa, 0xfb, 0x30, 0x0, 0x6, 0xff, 0x20, 0x0, + 0x0, 0x2, 0x50, 0x0, 0x0, 0x0, 0x26, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x86, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xca, 0x0, 0x0, 0x0, 0x0, + + /* U+F240 "" */ + 0x19, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb8, 0x0, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0xfc, 0x1, 0x11, 0x11, 0x11, 0x11, 0xe, 0xd0, + 0xfc, 0x6f, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xf9, + 0xfc, 0x6f, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xfb, + 0xfc, 0x6f, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xfb, + 0xfc, 0x26, 0x66, 0x66, 0x66, 0x66, 0x1e, 0xe2, + 0xdf, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb0, + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F241 "" */ + 0x19, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb8, 0x0, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0xfc, 0x1, 0x11, 0x11, 0x11, 0x0, 0xe, 0xd0, + 0xfc, 0x6f, 0xff, 0xff, 0xf9, 0x0, 0xe, 0xf9, + 0xfc, 0x6f, 0xff, 0xff, 0xf9, 0x0, 0xe, 0xfb, + 0xfc, 0x6f, 0xff, 0xff, 0xf9, 0x0, 0xe, 0xfb, + 0xfc, 0x26, 0x66, 0x66, 0x64, 0x0, 0xe, 0xe2, + 0xdf, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb0, + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F242 "" */ + 0x19, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb8, 0x0, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0xfc, 0x1, 0x11, 0x11, 0x0, 0x0, 0xe, 0xd0, + 0xfc, 0x6f, 0xff, 0xfd, 0x0, 0x0, 0xe, 0xf9, + 0xfc, 0x6f, 0xff, 0xfd, 0x0, 0x0, 0xe, 0xfb, + 0xfc, 0x6f, 0xff, 0xfd, 0x0, 0x0, 0xe, 0xfb, + 0xfc, 0x26, 0x66, 0x65, 0x0, 0x0, 0xe, 0xe2, + 0xdf, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb0, + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F243 "" */ + 0x19, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb8, 0x0, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0xfc, 0x1, 0x10, 0x0, 0x0, 0x0, 0xe, 0xd0, + 0xfc, 0x6f, 0xf4, 0x0, 0x0, 0x0, 0xe, 0xf9, + 0xfc, 0x6f, 0xf4, 0x0, 0x0, 0x0, 0xe, 0xfb, + 0xfc, 0x6f, 0xf4, 0x0, 0x0, 0x0, 0xe, 0xfb, + 0xfc, 0x26, 0x61, 0x0, 0x0, 0x0, 0xe, 0xe2, + 0xdf, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb0, + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F244 "" */ + 0x19, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb8, 0x0, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xd0, + 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xf9, + 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xfb, + 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xfb, + 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xe2, + 0xdf, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xb0, + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F287 "" */ + 0x0, 0x0, 0x0, 0x0, 0x4, 0xa4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xcf, 0xfd, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7b, 0x3b, 0xf9, + 0x0, 0x0, 0x0, 0x3, 0x40, 0x0, 0xe2, 0x0, + 0x10, 0x0, 0x0, 0x0, 0x6f, 0xfb, 0x7, 0xa0, + 0x0, 0x0, 0x0, 0x2e, 0x50, 0xbf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x7f, 0xfc, + 0x0, 0xa, 0x80, 0x0, 0x0, 0x3f, 0x70, 0x5, + 0x61, 0x0, 0x1, 0xe0, 0x0, 0x0, 0x1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x98, 0xd, 0xeb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xef, 0xfd, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, + 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+F293 "" */ + 0x0, 0x0, 0x1, 0x21, 0x0, 0x0, 0x0, 0x8, + 0xef, 0xff, 0xc3, 0x0, 0x0, 0xaf, 0xfd, 0x8f, + 0xff, 0x30, 0x4, 0xff, 0xfd, 0x9, 0xff, 0xb0, + 0xa, 0xfe, 0xfd, 0x12, 0xaf, 0xf1, 0xe, 0xf5, + 0x5d, 0x2c, 0xe, 0xf3, 0xf, 0xff, 0x33, 0x12, + 0xaf, 0xf5, 0x1f, 0xff, 0xf3, 0x8, 0xff, 0xf6, + 0xf, 0xff, 0xe2, 0x5, 0xff, 0xf6, 0xf, 0xfe, + 0x25, 0x14, 0x6f, 0xf5, 0xd, 0xf5, 0x7d, 0x2c, + 0xd, 0xf3, 0x9, 0xff, 0xfd, 0x0, 0xbf, 0xf0, + 0x2, 0xff, 0xfe, 0xb, 0xff, 0x90, 0x0, 0x6f, + 0xfe, 0xbf, 0xfd, 0x10, 0x0, 0x3, 0x9c, 0xcb, + 0x71, 0x0, + + /* U+F2ED "" */ + 0x0, 0x0, 0x34, 0x43, 0x0, 0x0, 0x3, 0x66, + 0x9f, 0xff, 0xfb, 0x66, 0x40, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x23, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x40, 0x1c, 0xcc, 0xcc, 0xcc, 0xcc, 0xc4, + 0x2, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x2f, + 0xf3, 0xfb, 0x7f, 0x6d, 0xf6, 0x2, 0xff, 0x2f, + 0xb7, 0xf5, 0xdf, 0x60, 0x2f, 0xf2, 0xfb, 0x7f, + 0x5d, 0xf6, 0x2, 0xff, 0x2f, 0xb7, 0xf5, 0xdf, + 0x60, 0x2f, 0xf2, 0xfb, 0x7f, 0x5d, 0xf6, 0x2, + 0xff, 0x2f, 0xb7, 0xf5, 0xdf, 0x60, 0x2f, 0xf3, + 0xfb, 0x7f, 0x6d, 0xf6, 0x0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x30, 0x4, 0xbc, 0xcc, 0xcc, 0xcb, + 0x70, 0x0, + + /* U+F304 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5, 0xff, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x2, 0xff, 0xff, 0x80, 0x0, + 0x0, 0x0, 0x5, 0x48, 0xff, 0xfe, 0x0, 0x0, + 0x0, 0x5, 0xff, 0x48, 0xff, 0xa0, 0x0, 0x0, + 0x5, 0xff, 0xff, 0x48, 0xc0, 0x0, 0x0, 0x5, + 0xff, 0xff, 0xff, 0x30, 0x0, 0x0, 0x5, 0xff, + 0xff, 0xff, 0xc0, 0x0, 0x0, 0x4, 0xff, 0xff, + 0xff, 0xc0, 0x0, 0x0, 0x4, 0xff, 0xff, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0xef, 0xff, 0xff, 0xc0, + 0x0, 0x0, 0x0, 0x4f, 0xff, 0xff, 0xc0, 0x0, + 0x0, 0x0, 0x8, 0xff, 0xff, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0xdf, 0xfe, 0x80, 0x0, 0x0, 0x0, + 0x0, 0xa, 0x83, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+F379 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x7d, 0xff, 0xd7, 0x10, 0x0, 0x0, 0x4e, + 0xff, 0xff, 0xff, 0xe4, 0x0, 0x3, 0xff, 0xff, + 0xbc, 0xdf, 0xff, 0x30, 0xe, 0xff, 0xc5, 0x38, + 0x7f, 0xff, 0xe0, 0x5f, 0xff, 0xf6, 0x13, 0x1a, + 0xff, 0xf5, 0x9f, 0xff, 0xf4, 0x5f, 0x52, 0xff, + 0xf9, 0xbf, 0xff, 0xf0, 0x23, 0x8, 0xff, 0xfb, + 0xaf, 0xff, 0xc0, 0xdc, 0x16, 0xff, 0xfa, 0x8f, + 0xfa, 0x0, 0x9a, 0x5, 0xff, 0xf8, 0x2f, 0xff, + 0xc3, 0x14, 0x4d, 0xff, 0xf2, 0x9, 0xff, 0xdc, + 0x5f, 0xff, 0xff, 0x90, 0x0, 0xbf, 0xff, 0xff, + 0xff, 0xfb, 0x0, 0x0, 0x8, 0xff, 0xff, 0xff, + 0x80, 0x0, 0x0, 0x0, 0x5, 0x77, 0x50, 0x0, + 0x0, + + /* U+F55A "" */ + 0x0, 0x0, 0x17, 0x77, 0x77, 0x77, 0x77, 0x50, + 0x0, 0x2, 0xef, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x0, 0x3e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0x3, 0xef, 0xff, 0xf9, 0xbf, 0xd7, 0xff, 0xfb, + 0x3e, 0xff, 0xff, 0xf7, 0x9, 0x14, 0xff, 0xfb, + 0xdf, 0xff, 0xff, 0xff, 0x50, 0x2f, 0xff, 0xfb, + 0x9f, 0xff, 0xff, 0xfd, 0x11, 0xb, 0xff, 0xfb, + 0x9, 0xff, 0xff, 0xf4, 0x3f, 0x61, 0xff, 0xfb, + 0x0, 0x9f, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfb, + 0x0, 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0x0, 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xd3, + + /* U+F7C2 "" */ + 0x0, 0x0, 0x11, 0x11, 0x10, 0x0, 0x6, 0xff, + 0xff, 0xff, 0xe3, 0x6, 0xfd, 0xfd, 0xef, 0xdf, + 0x96, 0xff, 0x1d, 0x3, 0xa1, 0xfa, 0xef, 0xf1, + 0xd1, 0x4a, 0x1f, 0xaf, 0xff, 0xdf, 0xde, 0xfd, + 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, + 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xff, 0xff, + 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xae, + 0xff, 0xff, 0xff, 0xff, 0xf9, 0x5d, 0xee, 0xee, + 0xee, 0xec, 0x10, + + /* U+F8A2 "" */ + 0x0, 0x2, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2e, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x2, 0xef, + 0x70, 0x0, 0x0, 0x0, 0x0, 0x2e, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfd, 0xaf, 0xfb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xb7, 0xa, 0xfb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xaf, 0xb0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 134, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 0, .adv_w = 134, .box_w = 3, .box_h = 9, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 14, .adv_w = 134, .box_w = 6, .box_h = 5, .ofs_x = 1, .ofs_y = 5}, + {.bitmap_index = 29, .adv_w = 134, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 65, .adv_w = 134, .box_w = 7, .box_h = 13, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 111, .adv_w = 134, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 152, .adv_w = 134, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 187, .adv_w = 134, .box_w = 3, .box_h = 5, .ofs_x = 3, .ofs_y = 5}, + {.bitmap_index = 195, .adv_w = 134, .box_w = 4, .box_h = 13, .ofs_x = 2, .ofs_y = -3}, + {.bitmap_index = 221, .adv_w = 134, .box_w = 5, .box_h = 13, .ofs_x = 2, .ofs_y = -3}, + {.bitmap_index = 254, .adv_w = 134, .box_w = 8, .box_h = 8, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 286, .adv_w = 134, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 311, .adv_w = 134, .box_w = 4, .box_h = 5, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 321, .adv_w = 134, .box_w = 7, .box_h = 2, .ofs_x = 1, .ofs_y = 3}, + {.bitmap_index = 328, .adv_w = 134, .box_w = 3, .box_h = 3, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 333, .adv_w = 134, .box_w = 7, .box_h = 13, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 379, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 411, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 443, .adv_w = 134, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 470, .adv_w = 134, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 497, .adv_w = 134, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 533, .adv_w = 134, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 560, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 592, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 624, .adv_w = 134, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 651, .adv_w = 134, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 678, .adv_w = 134, .box_w = 3, .box_h = 7, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 689, .adv_w = 134, .box_w = 4, .box_h = 9, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 707, .adv_w = 134, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 735, .adv_w = 134, .box_w = 7, .box_h = 5, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 753, .adv_w = 134, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 778, .adv_w = 134, .box_w = 6, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 808, .adv_w = 134, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 844, .adv_w = 134, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 880, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 912, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 944, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 976, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1008, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1040, .adv_w = 134, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1076, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1108, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1140, .adv_w = 134, .box_w = 6, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1167, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1199, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1231, .adv_w = 134, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1267, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1299, .adv_w = 134, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1335, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1367, .adv_w = 134, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1407, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1439, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1471, .adv_w = 134, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1507, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1539, .adv_w = 134, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1575, .adv_w = 134, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1611, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1643, .adv_w = 134, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1679, .adv_w = 134, .box_w = 7, .box_h = 9, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1711, .adv_w = 134, .box_w = 4, .box_h = 14, .ofs_x = 2, .ofs_y = -3}, + {.bitmap_index = 1739, .adv_w = 134, .box_w = 7, .box_h = 13, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 1785, .adv_w = 134, .box_w = 5, .box_h = 14, .ofs_x = 2, .ofs_y = -3}, + {.bitmap_index = 1820, .adv_w = 134, .box_w = 6, .box_h = 5, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 1835, .adv_w = 134, .box_w = 8, .box_h = 2, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 1843, .adv_w = 134, .box_w = 4, .box_h = 3, .ofs_x = 2, .ofs_y = 8}, + {.bitmap_index = 1849, .adv_w = 134, .box_w = 6, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1870, .adv_w = 134, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1905, .adv_w = 134, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1930, .adv_w = 134, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1970, .adv_w = 134, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1995, .adv_w = 134, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2030, .adv_w = 134, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2070, .adv_w = 134, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2105, .adv_w = 134, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2140, .adv_w = 134, .box_w = 6, .box_h = 13, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 2179, .adv_w = 134, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2214, .adv_w = 134, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2249, .adv_w = 134, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2277, .adv_w = 134, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2302, .adv_w = 134, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2330, .adv_w = 134, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 2365, .adv_w = 134, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2405, .adv_w = 134, .box_w = 6, .box_h = 7, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 2426, .adv_w = 134, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2451, .adv_w = 134, .box_w = 8, .box_h = 9, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2487, .adv_w = 134, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2512, .adv_w = 134, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2540, .adv_w = 134, .box_w = 8, .box_h = 7, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2568, .adv_w = 134, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2593, .adv_w = 134, .box_w = 8, .box_h = 10, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 2633, .adv_w = 134, .box_w = 7, .box_h = 7, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2658, .adv_w = 134, .box_w = 6, .box_h = 14, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 2700, .adv_w = 134, .box_w = 2, .box_h = 13, .ofs_x = 3, .ofs_y = -3}, + {.bitmap_index = 2713, .adv_w = 134, .box_w = 7, .box_h = 14, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 2762, .adv_w = 134, .box_w = 7, .box_h = 3, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 2773, .adv_w = 134, .box_w = 5, .box_h = 4, .ofs_x = 1, .ofs_y = 5}, + {.bitmap_index = 2783, .adv_w = 134, .box_w = 4, .box_h = 4, .ofs_x = 2, .ofs_y = 3}, + {.bitmap_index = 2791, .adv_w = 140, .box_w = 9, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2859, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 2972, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3063, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3154, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3224, .adv_w = 140, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 3269, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 3374, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 3479, .adv_w = 252, .box_w = 16, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 3599, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 3704, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3795, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3886, .adv_w = 140, .box_w = 9, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3945, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 4030, .adv_w = 280, .box_w = 18, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4156, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 4247, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4330, .adv_w = 140, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 4384, .adv_w = 168, .box_w = 11, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4461, .adv_w = 140, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4511, .adv_w = 168, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4572, .adv_w = 140, .box_w = 9, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 4626, .adv_w = 196, .box_w = 14, .box_h = 13, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 4717, .adv_w = 168, .box_w = 8, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 4769, .adv_w = 168, .box_w = 8, .box_h = 13, .ofs_x = 2, .ofs_y = -1}, + {.bitmap_index = 4821, .adv_w = 196, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 4893, .adv_w = 196, .box_w = 12, .box_h = 2, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 4905, .adv_w = 252, .box_w = 17, .box_h = 13, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 5016, .adv_w = 280, .box_w = 19, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 5159, .adv_w = 224, .box_w = 16, .box_h = 13, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 5263, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 5361, .adv_w = 224, .box_w = 14, .box_h = 8, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 5417, .adv_w = 224, .box_w = 14, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 5473, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 5561, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 5652, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 5757, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 5870, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 5975, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 6080, .adv_w = 196, .box_w = 13, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 6165, .adv_w = 196, .box_w = 13, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 6237, .adv_w = 224, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 6314, .adv_w = 196, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 6404, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 6509, .adv_w = 196, .box_w = 14, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 6614, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 6702, .adv_w = 196, .box_w = 12, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 6780, .adv_w = 168, .box_w = 11, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 6852, .adv_w = 280, .box_w = 18, .box_h = 13, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 6969, .adv_w = 252, .box_w = 16, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7049, .adv_w = 252, .box_w = 16, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7129, .adv_w = 252, .box_w = 16, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7209, .adv_w = 252, .box_w = 16, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7289, .adv_w = 252, .box_w = 16, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7369, .adv_w = 280, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 7477, .adv_w = 196, .box_w = 12, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 7567, .adv_w = 196, .box_w = 13, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 7665, .adv_w = 224, .box_w = 15, .box_h = 15, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 7778, .adv_w = 224, .box_w = 14, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 7883, .adv_w = 252, .box_w = 16, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7971, .adv_w = 168, .box_w = 11, .box_h = 15, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 8054, .adv_w = 224, .box_w = 14, .box_h = 10, .ofs_x = 0, .ofs_y = 0} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_1[] = { + 0x0, 0x1f72, 0xe004, 0xef51, 0xef58, 0xef5b, 0xef5c, 0xef5d, + 0xef61, 0xef63, 0xef65, 0xef69, 0xef6c, 0xef71, 0xef76, 0xef77, + 0xef78, 0xef8e, 0xef93, 0xef98, 0xef9b, 0xef9c, 0xef9d, 0xefa1, + 0xefa2, 0xefa3, 0xefa4, 0xefb7, 0xefb8, 0xefbe, 0xefc0, 0xefc1, + 0xefc4, 0xefc7, 0xefc8, 0xefc9, 0xefcb, 0xefe3, 0xefe5, 0xf014, + 0xf015, 0xf017, 0xf019, 0xf030, 0xf037, 0xf03a, 0xf043, 0xf06c, + 0xf074, 0xf0a8, 0xf13b, 0xf190, 0xf191, 0xf192, 0xf193, 0xf194, + 0xf1d7, 0xf1e3, 0xf23d, 0xf254, 0xf2c9, 0xf4aa, 0xf712, 0xf7f2 +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 95, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 176, .range_length = 63475, .glyph_id_start = 96, + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 64, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + + + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LVGL_VERSION_MAJOR >= 8 +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 2, + .bpp = 4, + .kern_classes = 0, + .bitmap_format = 0, +#if LVGL_VERSION_MAJOR >= 8 + .cache = &cache +#endif +}; + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t lv_font_courierprimecode_14 = { +#else +lv_font_t lv_font_courierprimecode_14 = { +#endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 17, /*The maximum line height required by the font*/ + .base_line = 4, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -1, + .underline_thickness = 1, +#endif + .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +}; + + + +#endif /*#if LV_FONT_COURIERPRIMECODE_14*/ + diff --git a/src/ui/c/lv_font_courierprimecode_16.c b/src/ui/c/lv_font_courierprimecode_16.c new file mode 100644 index 0000000..bb4aa66 --- /dev/null +++ b/src/ui/c/lv_font_courierprimecode_16.c @@ -0,0 +1,1899 @@ +/******************************************************************************* + * Size: 16 px + * Bpp: 4 + * Opts: --no-compress --no-prefilter --bpp 4 --size 16 --font courier-prime-code.ttf -r 0x20-0x7F,0xB0,0x2022 --font fa-brands-400.ttf -r 0xF287,0xF293,0xF379 --font fa-solid-900.ttf -r 0xF001,0xF008,0xF00B,0xF00C,0xF00D,0xF011,0xF013,0xF015,0xF019,0xF01C,0xF021,0xF026,0xF027,0xF028,0xF03E,0xF043,0xF048,0xF04B,0xF04C,0xF04D,0xF051,0xF052,0xF053,0xF054,0xF067,0xF068,0xF06E,0xF070,0xF071,0xF074,0xF077,0xF078,0xF079,0xF07B,0xF093,0xF095,0xF0C4,0xF0C5,0xF0C7,0xF0C9,0xF0E0,0xF0E7,0xF0EA,0xF0F3,0xF11C,0xF124,0xF158,0xF1EB,0xF240,0xF241,0xF242,0xF243,0xF244,0xF2ED,0xF304,0xF55A,0xF7C2,0xF177=>0xF8A2,0xE0B4,0xF0E7 --format lvgl -o lv_font_courierprimecode_16.c --force-fast-kern-format + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef LV_FONT_COURIERPRIMECODE_16 +#define LV_FONT_COURIERPRIMECODE_16 1 +#endif + +#if LV_FONT_COURIERPRIMECODE_16 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + + /* U+0021 "!" */ + 0xc, 0x70, 0xf9, 0xe, 0x80, 0xd7, 0xc, 0x60, + 0xb5, 0x9, 0x30, 0x0, 0x5, 0x22, 0xfc, 0x1f, + 0xa0, + + /* U+0022 "\"" */ + 0x9a, 0x3, 0xb6, 0xde, 0x3, 0xf8, 0xbc, 0x2, + 0xf6, 0x9b, 0x0, 0xf4, 0x78, 0x0, 0xd2, + + /* U+0023 "#" */ + 0x0, 0x1, 0xc0, 0xd, 0x0, 0x0, 0x5, 0xa0, + 0x4c, 0x0, 0x0, 0x9, 0x70, 0x88, 0x0, 0xe, + 0xff, 0xff, 0xff, 0xf1, 0x2, 0x4f, 0x33, 0xf3, + 0x20, 0x0, 0x5b, 0x4, 0xc0, 0x0, 0x7f, 0xff, + 0xff, 0xff, 0x70, 0x3, 0xe5, 0x3d, 0x63, 0x10, + 0x1, 0xe0, 0xf, 0x0, 0x0, 0x4, 0x90, 0x3b, + 0x0, 0x0, + + /* U+0024 "$" */ + 0x0, 0x2, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, + 0x0, 0xc, 0x40, 0x0, 0x7, 0xef, 0xfb, 0x40, + 0x4f, 0x63, 0x5a, 0xc0, 0x8b, 0x0, 0x0, 0x0, + 0x6f, 0x84, 0x20, 0x0, 0x8, 0xef, 0xfe, 0x50, + 0x0, 0x1, 0x4a, 0xf1, 0x0, 0x0, 0x0, 0xf3, + 0x7b, 0x41, 0x18, 0xf0, 0x2b, 0xff, 0xff, 0x50, + 0x0, 0xd, 0x60, 0x0, 0x0, 0xc, 0x40, 0x0, + 0x0, 0x7, 0x20, 0x0, + + /* U+0025 "%" */ + 0xa, 0xfb, 0x0, 0x0, 0x0, 0x7b, 0x2a, 0x80, + 0x6, 0x80, 0x89, 0x9, 0x90, 0x7e, 0x30, 0x1d, + 0xfd, 0x17, 0xe3, 0x0, 0x0, 0x10, 0x7e, 0x20, + 0x0, 0x0, 0x8, 0xe5, 0xdd, 0x30, 0x0, 0x8e, + 0x2d, 0x75, 0xe0, 0x8, 0xe2, 0xf, 0x0, 0xd2, + 0xc, 0x20, 0xd, 0x64, 0xe0, 0x0, 0x0, 0x3, + 0xee, 0x40, + + /* U+0026 "&" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0xe9, 0x10, + 0x9, 0xd5, 0x5c, 0x40, 0xe, 0x50, 0x0, 0x0, + 0xd, 0x50, 0x0, 0x0, 0x9, 0xc0, 0x0, 0x0, + 0x9, 0xf9, 0x0, 0xd2, 0x5f, 0x5f, 0x63, 0xf0, + 0xb8, 0x4, 0xfc, 0xa0, 0xb8, 0x0, 0x8f, 0x50, + 0x6e, 0x55, 0xde, 0xd1, 0x8, 0xee, 0x80, 0xc5, + + /* U+0027 "'" */ + 0x1a, 0x71, 0xfa, 0xf, 0x80, 0xd7, 0xa, 0x40, + + /* U+0028 "(" */ + 0x0, 0x2, 0x40, 0x3, 0xf8, 0x1, 0xe8, 0x0, + 0xab, 0x0, 0x1f, 0x30, 0x6, 0xc0, 0x0, 0x99, + 0x0, 0xa, 0x80, 0x0, 0x99, 0x0, 0x7, 0xb0, + 0x0, 0x3f, 0x0, 0x0, 0xd7, 0x0, 0x4, 0xf3, + 0x0, 0x9, 0xe3, 0x0, 0x8, 0x90, + + /* U+0029 ")" */ + 0x1d, 0x30, 0x0, 0x8, 0xf3, 0x0, 0x0, 0x9d, + 0x0, 0x0, 0xd, 0x60, 0x0, 0x6, 0xd0, 0x0, + 0x1, 0xf1, 0x0, 0x0, 0xf3, 0x0, 0x0, 0xe4, + 0x0, 0x0, 0xf2, 0x0, 0x3, 0xf0, 0x0, 0x9, + 0xa0, 0x0, 0x2f, 0x30, 0x1, 0xd9, 0x0, 0xd, + 0xb0, 0x0, 0x6, 0x0, 0x0, + + /* U+002A "*" */ + 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, 0xe, 0x70, + 0x0, 0x0, 0x0, 0xc6, 0x0, 0x1, 0xe9, 0x1b, + 0x44, 0xc9, 0x9, 0xef, 0xed, 0xfc, 0x50, 0x0, + 0x3f, 0xc0, 0x0, 0x0, 0xd, 0x6d, 0x70, 0x0, + 0xa, 0xe0, 0x5f, 0x40, 0x0, 0xd5, 0x0, 0xc6, + 0x0, + + /* U+002B "+" */ + 0x0, 0x4, 0x10, 0x0, 0x0, 0xc, 0x50, 0x0, + 0x0, 0xc, 0x50, 0x0, 0x0, 0xc, 0x50, 0x0, + 0x9f, 0xff, 0xff, 0xf3, 0x13, 0x3d, 0x73, 0x30, + 0x0, 0xc, 0x50, 0x0, 0x0, 0xb, 0x40, 0x0, + + /* U+002C "," */ + 0x5, 0xfb, 0x8, 0xf6, 0xb, 0xf0, 0xe, 0x90, + 0xf, 0x30, + + /* U+002D "-" */ + 0x0, 0x0, 0x0, 0x0, 0x9f, 0xff, 0xff, 0xf3, + 0x13, 0x33, 0x33, 0x30, + + /* U+002E "." */ + 0x19, 0x64, 0xfd, 0x2f, 0xc0, + + /* U+002F "/" */ + 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x9, 0xb0, + 0x0, 0x0, 0xf, 0x50, 0x0, 0x0, 0x5e, 0x0, + 0x0, 0x0, 0xb9, 0x0, 0x0, 0x1, 0xf3, 0x0, + 0x0, 0x7, 0xd0, 0x0, 0x0, 0xd, 0x70, 0x0, + 0x0, 0x3f, 0x10, 0x0, 0x0, 0x9b, 0x0, 0x0, + 0x0, 0xe5, 0x0, 0x0, 0x5, 0xf0, 0x0, 0x0, + 0xb, 0x90, 0x0, 0x0, 0x1f, 0x30, 0x0, 0x0, + 0x5c, 0x0, 0x0, 0x0, + + /* U+0030 "0" */ + 0x0, 0xaf, 0xd5, 0x0, 0xa, 0xd5, 0x7f, 0x40, + 0x2f, 0x20, 0xd, 0xb0, 0x6d, 0x0, 0x9e, 0xf0, + 0x7b, 0x7, 0xd3, 0xf1, 0x7b, 0x5e, 0x22, 0xf1, + 0x6e, 0xf3, 0x4, 0xf0, 0x2f, 0x70, 0x9, 0xb0, + 0xa, 0xd5, 0x7f, 0x40, 0x0, 0xaf, 0xd5, 0x0, + + /* U+0031 "1" */ + 0x0, 0x1a, 0x90, 0x0, 0x5, 0xef, 0xa0, 0x0, + 0x2f, 0x68, 0xa0, 0x0, 0x0, 0x8, 0xa0, 0x0, + 0x0, 0x8, 0xa0, 0x0, 0x0, 0x8, 0xa0, 0x0, + 0x0, 0x8, 0xa0, 0x0, 0x0, 0x8, 0xa0, 0x0, + 0x3, 0x3a, 0xb3, 0x30, 0x1f, 0xff, 0xff, 0xf0, + + /* U+0032 "2" */ + 0x6, 0xcf, 0xd6, 0x3, 0xf8, 0x47, 0xf4, 0x0, + 0x0, 0xa, 0x90, 0x0, 0x0, 0xb8, 0x0, 0x0, + 0x3f, 0x20, 0x0, 0x2e, 0x70, 0x0, 0x1e, 0x90, + 0x0, 0x1d, 0xa0, 0x0, 0x1d, 0xd3, 0x33, 0x25, + 0xff, 0xff, 0xfd, + + /* U+0033 "3" */ + 0x7, 0xdf, 0xd6, 0x2, 0xc7, 0x47, 0xf4, 0x0, + 0x0, 0xb, 0x70, 0x0, 0x3, 0xe4, 0x0, 0x5f, + 0xfa, 0x0, 0x0, 0x25, 0xe5, 0x0, 0x0, 0x7, + 0xb0, 0x10, 0x0, 0x8b, 0x7e, 0x74, 0x7f, 0x60, + 0x6d, 0xfe, 0x70, + + /* U+0034 "4" */ + 0x0, 0x1, 0xd7, 0x0, 0x0, 0xa, 0xf8, 0x0, + 0x0, 0x5e, 0x98, 0x0, 0x1, 0xe4, 0x98, 0x0, + 0xa, 0xa0, 0x98, 0x0, 0x4e, 0x10, 0xa8, 0x0, + 0xcf, 0xff, 0xff, 0xf3, 0x23, 0x33, 0xba, 0x30, + 0x0, 0x0, 0xa8, 0x0, 0x0, 0x0, 0x87, 0x0, + + /* U+0035 "5" */ + 0xc, 0xff, 0xff, 0x50, 0xe6, 0x33, 0x30, 0xe, + 0x30, 0x0, 0x0, 0xfc, 0xfe, 0x80, 0xd, 0x84, + 0x6f, 0x60, 0x0, 0x0, 0x8c, 0x0, 0x0, 0x6, + 0xd0, 0x10, 0x0, 0x9b, 0x6f, 0x84, 0x7f, 0x40, + 0x6d, 0xfd, 0x60, + + /* U+0036 "6" */ + 0x0, 0x6, 0xce, 0x80, 0x0, 0xbe, 0x85, 0x20, + 0x8, 0xe1, 0x0, 0x0, 0xf, 0x50, 0x0, 0x0, + 0x4f, 0x8f, 0xfa, 0x10, 0x6f, 0xb4, 0x5d, 0xb0, + 0x5f, 0x0, 0x4, 0xf0, 0x2f, 0x10, 0x4, 0xf0, + 0xb, 0xc5, 0x6d, 0xa0, 0x1, 0xaf, 0xe9, 0x0, + + /* U+0037 "7" */ + 0x5f, 0xff, 0xff, 0xf0, 0x3, 0x33, 0x39, 0xc0, + 0x0, 0x0, 0xd, 0x60, 0x0, 0x0, 0x4f, 0x0, + 0x0, 0x0, 0xa9, 0x0, 0x0, 0x1, 0xf3, 0x0, + 0x0, 0x6, 0xd0, 0x0, 0x0, 0xc, 0x70, 0x0, + 0x0, 0x3f, 0x10, 0x0, 0x0, 0x6a, 0x0, 0x0, + + /* U+0038 "8" */ + 0x1, 0xbf, 0xe7, 0x0, 0xcc, 0x56, 0xf6, 0xf, + 0x30, 0x9, 0xa0, 0xc9, 0x2, 0xd6, 0x2, 0xff, + 0xfb, 0x0, 0xda, 0x45, 0xe7, 0x4f, 0x0, 0x5, + 0xe4, 0xf0, 0x0, 0x6e, 0xe, 0xb5, 0x6f, 0x80, + 0x2b, 0xfe, 0x80, + + /* U+0039 "9" */ + 0x3, 0xcf, 0xd6, 0x0, 0x1f, 0xa5, 0x7f, 0x50, + 0x6d, 0x0, 0x8, 0xb0, 0x7d, 0x0, 0x6, 0xe0, + 0x2f, 0x71, 0x3d, 0xf0, 0x6, 0xff, 0xfb, 0xe0, + 0x0, 0x3, 0xa, 0x90, 0x0, 0x0, 0x6f, 0x20, + 0x4, 0x6b, 0xf6, 0x0, 0xe, 0xea, 0x30, 0x0, + + /* U+003A ":" */ + 0x2f, 0xb4, 0xfd, 0x19, 0x60, 0x0, 0x0, 0x1, + 0x96, 0x4f, 0xd2, 0xfc, + + /* U+003B ";" */ + 0x2f, 0xb0, 0x4f, 0xd0, 0x19, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0xe0, 0x6f, 0x90, 0x9f, 0x20, + 0xcc, 0x0, 0xd5, 0x0, + + /* U+003C "<" */ + 0x0, 0x0, 0x0, 0x4b, 0x10, 0x0, 0x3, 0xcf, + 0x80, 0x0, 0x2b, 0xf9, 0x10, 0x0, 0x9f, 0xa2, + 0x0, 0x0, 0xc, 0xf7, 0x0, 0x0, 0x0, 0x5, + 0xde, 0x70, 0x0, 0x0, 0x0, 0x6e, 0xe6, 0x0, + 0x0, 0x0, 0x6, 0xe2, + + /* U+003D "=" */ + 0x0, 0x0, 0x0, 0x0, 0x9f, 0xff, 0xff, 0xf3, + 0x13, 0x33, 0x33, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x9f, 0xff, 0xff, 0xf3, 0x13, 0x33, 0x33, 0x30, + + /* U+003E ">" */ + 0x69, 0x10, 0x0, 0x0, 0x2c, 0xf8, 0x10, 0x0, + 0x0, 0x4c, 0xf7, 0x0, 0x0, 0x0, 0x5d, 0xe4, + 0x0, 0x0, 0x2b, 0xf6, 0x0, 0x2a, 0xfa, 0x20, + 0x19, 0xfb, 0x20, 0x0, 0x7c, 0x30, 0x0, 0x0, + + /* U+003F "?" */ + 0x0, 0x0, 0x0, 0x6d, 0xfe, 0x70, 0xb8, 0x46, + 0xf4, 0x0, 0x0, 0xb8, 0x0, 0x1, 0xe6, 0x0, + 0x7e, 0xc0, 0x1, 0xf7, 0x0, 0x1, 0xf1, 0x0, + 0x0, 0x70, 0x0, 0x0, 0x0, 0x0, 0x5, 0xf4, + 0x0, 0x5, 0xf4, 0x0, + + /* U+0040 "@" */ + 0x0, 0x18, 0xdd, 0xa2, 0x0, 0x2, 0xe9, 0x32, + 0x7e, 0x20, 0xc, 0x62, 0xca, 0x86, 0xa0, 0x3c, + 0xc, 0x7a, 0xd0, 0xe0, 0x77, 0x3e, 0x8, 0xa0, + 0xd1, 0x96, 0x6a, 0xb, 0x70, 0xe1, 0x87, 0x6a, + 0x3f, 0x74, 0xd0, 0x4c, 0x1e, 0xe5, 0xff, 0x40, + 0xc, 0x91, 0x0, 0x10, 0x0, 0x1, 0xaf, 0xff, + 0x90, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, + + /* U+0041 "A" */ + 0x0, 0x1, 0xe9, 0x0, 0x0, 0x0, 0x7d, 0xf0, + 0x0, 0x0, 0xc, 0x6d, 0x50, 0x0, 0x2, 0xf1, + 0x7b, 0x0, 0x0, 0x8b, 0x2, 0xf1, 0x0, 0xd, + 0x60, 0xd, 0x60, 0x3, 0xff, 0xff, 0xfc, 0x0, + 0x8b, 0x33, 0x34, 0xf1, 0xe, 0x50, 0x0, 0xc, + 0x72, 0xe0, 0x0, 0x0, 0x6a, + + /* U+0042 "B" */ + 0x5f, 0xff, 0xfa, 0x10, 0x6d, 0x33, 0x4d, 0xa0, + 0x6c, 0x0, 0x6, 0xd0, 0x6c, 0x0, 0x1b, 0x90, + 0x6f, 0xff, 0xff, 0x30, 0x6d, 0x33, 0x39, 0xe1, + 0x6c, 0x0, 0x0, 0xe5, 0x6c, 0x0, 0x0, 0xe5, + 0x6d, 0x33, 0x49, 0xf1, 0x5f, 0xff, 0xfd, 0x40, + + /* U+0043 "C" */ + 0x0, 0x9e, 0xfc, 0x60, 0xc, 0xd6, 0x47, 0xe4, + 0x5e, 0x10, 0x0, 0x0, 0xa9, 0x0, 0x0, 0x0, + 0xc6, 0x0, 0x0, 0x0, 0xc6, 0x0, 0x0, 0x0, + 0xa9, 0x0, 0x0, 0x0, 0x5e, 0x10, 0x0, 0x0, + 0xc, 0xd5, 0x47, 0xe4, 0x0, 0x9e, 0xfc, 0x60, + + /* U+0044 "D" */ + 0x9f, 0xff, 0xd6, 0x0, 0xaa, 0x33, 0x7f, 0x80, + 0xa8, 0x0, 0x4, 0xf1, 0xa8, 0x0, 0x0, 0xd6, + 0xa8, 0x0, 0x0, 0xa8, 0xa8, 0x0, 0x0, 0xa8, + 0xa8, 0x0, 0x0, 0xd6, 0xa8, 0x0, 0x4, 0xf2, + 0xaa, 0x33, 0x7f, 0x80, 0x9f, 0xff, 0xd7, 0x0, + + /* U+0045 "E" */ + 0x2f, 0xff, 0xff, 0xe0, 0x3f, 0x33, 0x33, 0x20, + 0x3f, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x0, 0x0, + 0x3f, 0xff, 0xfe, 0x0, 0x3f, 0x33, 0x32, 0x0, + 0x3f, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x0, 0x0, + 0x3f, 0x33, 0x33, 0x30, 0x2f, 0xff, 0xff, 0xf1, + + /* U+0046 "F" */ + 0xf, 0xff, 0xff, 0xf1, 0x1f, 0x43, 0x33, 0x20, + 0x1f, 0x10, 0x0, 0x0, 0x1f, 0x10, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0x20, 0x1f, 0x43, 0x33, 0x0, + 0x1f, 0x10, 0x0, 0x0, 0x1f, 0x10, 0x0, 0x0, + 0x1f, 0x10, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, + + /* U+0047 "G" */ + 0x0, 0x2a, 0xef, 0xc6, 0x0, 0x1e, 0xc5, 0x48, + 0xd2, 0x9, 0xc0, 0x0, 0x0, 0x0, 0xf4, 0x0, + 0x0, 0x0, 0x1f, 0x10, 0x0, 0x0, 0x1, 0xf1, + 0x3, 0xff, 0xf6, 0xf, 0x40, 0x2, 0x3c, 0x70, + 0xab, 0x0, 0x0, 0xb7, 0x2, 0xeb, 0x54, 0x7e, + 0x70, 0x2, 0xbf, 0xfc, 0x71, + + /* U+0048 "H" */ + 0x87, 0x0, 0x0, 0xd2, 0xa8, 0x0, 0x0, 0xf3, + 0xa8, 0x0, 0x0, 0xf3, 0xa8, 0x0, 0x0, 0xf3, + 0xaf, 0xff, 0xff, 0xf3, 0xaa, 0x33, 0x33, 0xf3, + 0xa8, 0x0, 0x0, 0xf3, 0xa8, 0x0, 0x0, 0xf3, + 0xa8, 0x0, 0x0, 0xf3, 0x87, 0x0, 0x0, 0xd2, + + /* U+0049 "I" */ + 0x3f, 0xff, 0xff, 0xc0, 0x3, 0x3d, 0x83, 0x20, + 0x0, 0xc, 0x60, 0x0, 0x0, 0xc, 0x60, 0x0, + 0x0, 0xc, 0x60, 0x0, 0x0, 0xc, 0x60, 0x0, + 0x0, 0xc, 0x60, 0x0, 0x0, 0xc, 0x60, 0x0, + 0x3, 0x3d, 0x83, 0x20, 0x5f, 0xff, 0xff, 0xf0, + + /* U+004A "J" */ + 0x0, 0xff, 0xff, 0x60, 0x2, 0x33, 0xc7, 0x0, + 0x0, 0xb, 0x70, 0x0, 0x0, 0xb7, 0x0, 0x0, + 0xb, 0x70, 0x0, 0x0, 0xb7, 0x0, 0x0, 0xb, + 0x70, 0x0, 0x0, 0xd6, 0x7e, 0x74, 0x8f, 0x20, + 0x7d, 0xfd, 0x50, + + /* U+004B "K" */ + 0x4c, 0x0, 0x1, 0xd3, 0x5d, 0x0, 0x1d, 0xb0, + 0x5d, 0x0, 0xcc, 0x0, 0x5d, 0xb, 0xc0, 0x0, + 0x5d, 0xaf, 0x30, 0x0, 0x5f, 0xeb, 0xc0, 0x0, + 0x5f, 0x30, 0xd8, 0x0, 0x5d, 0x0, 0x3f, 0x40, + 0x5d, 0x0, 0x7, 0xe1, 0x4c, 0x0, 0x0, 0xb6, + + /* U+004C "L" */ + 0xe, 0x0, 0x0, 0x0, 0x1f, 0x10, 0x0, 0x0, + 0x1f, 0x10, 0x0, 0x0, 0x1f, 0x10, 0x0, 0x0, + 0x1f, 0x10, 0x0, 0x0, 0x1f, 0x10, 0x0, 0x0, + 0x1f, 0x10, 0x0, 0x0, 0x1f, 0x10, 0x0, 0x0, + 0x1f, 0x43, 0x33, 0x30, 0xf, 0xff, 0xff, 0xf1, + + /* U+004D "M" */ + 0x8a, 0x0, 0x1, 0xe2, 0xaf, 0x20, 0x8, 0xf4, + 0xaf, 0x90, 0xf, 0xf4, 0xba, 0xf1, 0x6c, 0xd4, + 0xb6, 0xc7, 0xd5, 0xd5, 0xc6, 0x5f, 0xe0, 0xc5, + 0xc5, 0xc, 0x60, 0xc6, 0xc5, 0x0, 0x0, 0xc6, + 0xd5, 0x0, 0x0, 0xb7, 0xc3, 0x0, 0x0, 0xa6, + + /* U+004E "N" */ + 0x8c, 0x0, 0x0, 0xd2, 0xaf, 0x60, 0x0, 0xe3, + 0xad, 0xf1, 0x0, 0xe3, 0xa8, 0xba, 0x0, 0xe3, + 0xa8, 0x2f, 0x40, 0xe3, 0xa8, 0x7, 0xd0, 0xe3, + 0xa8, 0x0, 0xd7, 0xe3, 0xa8, 0x0, 0x4f, 0xf3, + 0xa8, 0x0, 0xa, 0xf3, 0x87, 0x0, 0x1, 0xe2, + + /* U+004F "O" */ + 0x0, 0x3c, 0xfe, 0x90, 0x0, 0x4f, 0x94, 0x5d, + 0xc0, 0xd, 0x90, 0x0, 0x1e, 0x61, 0xf1, 0x0, + 0x0, 0x8b, 0x4f, 0x0, 0x0, 0x5, 0xd4, 0xf0, + 0x0, 0x0, 0x5d, 0x1f, 0x10, 0x0, 0x8, 0xb0, + 0xd9, 0x0, 0x1, 0xe6, 0x3, 0xf9, 0x45, 0xdc, + 0x0, 0x3, 0xcf, 0xe9, 0x0, + + /* U+0050 "P" */ + 0x1f, 0xff, 0xfb, 0x20, 0x2f, 0x33, 0x4b, 0xe0, + 0x2f, 0x0, 0x0, 0xf4, 0x2f, 0x0, 0x0, 0xe5, + 0x2f, 0x0, 0x18, 0xf1, 0x2f, 0xff, 0xfe, 0x50, + 0x2f, 0x33, 0x20, 0x0, 0x2f, 0x0, 0x0, 0x0, + 0x2f, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, + + /* U+0051 "Q" */ + 0x0, 0x3c, 0xfe, 0x90, 0x0, 0x4f, 0x94, 0x5d, + 0xc0, 0xd, 0x90, 0x0, 0x1e, 0x61, 0xf1, 0x0, + 0x0, 0x8b, 0x4f, 0x0, 0x0, 0x5, 0xd4, 0xf0, + 0x0, 0x0, 0x5d, 0x1f, 0x10, 0x25, 0x8, 0xb0, + 0xd9, 0x3, 0xf3, 0xe6, 0x3, 0xf9, 0x4c, 0xfc, + 0x0, 0x3, 0xcf, 0xef, 0x60, 0x0, 0x0, 0x0, + 0x5c, 0x0, + + /* U+0052 "R" */ + 0x1f, 0xff, 0xe9, 0x10, 0x2f, 0x33, 0x5d, 0xa0, + 0x2f, 0x0, 0x4, 0xf0, 0x2f, 0x0, 0x3, 0xf0, + 0x2f, 0x0, 0x2b, 0xc0, 0x2f, 0xff, 0xfd, 0x20, + 0x2f, 0x34, 0xf5, 0x0, 0x2f, 0x0, 0x6e, 0x10, + 0x2f, 0x0, 0xc, 0xa0, 0x1e, 0x0, 0x2, 0xe1, + + /* U+0053 "S" */ + 0x6, 0xdf, 0xea, 0x30, 0x5f, 0x74, 0x6a, 0xe0, + 0x9a, 0x0, 0x0, 0x0, 0x8d, 0x10, 0x0, 0x0, + 0x1c, 0xfd, 0xa5, 0x0, 0x0, 0x25, 0x9e, 0xb0, + 0x0, 0x0, 0x2, 0xf3, 0x10, 0x0, 0x0, 0xf4, + 0x9e, 0x74, 0x5b, 0xe0, 0x7, 0xcf, 0xfb, 0x20, + + /* U+0054 "T" */ + 0xf, 0xff, 0xff, 0xff, 0x80, 0x23, 0x3d, 0x83, + 0x31, 0x0, 0x0, 0xc6, 0x0, 0x0, 0x0, 0xc, + 0x60, 0x0, 0x0, 0x0, 0xc6, 0x0, 0x0, 0x0, + 0xc, 0x60, 0x0, 0x0, 0x0, 0xc6, 0x0, 0x0, + 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, 0xc6, 0x0, + 0x0, 0x0, 0xb, 0x50, 0x0, + + /* U+0055 "U" */ + 0x87, 0x0, 0x0, 0xd2, 0xa8, 0x0, 0x0, 0xf3, + 0xa8, 0x0, 0x0, 0xf3, 0xa8, 0x0, 0x0, 0xf3, + 0xa8, 0x0, 0x0, 0xf3, 0xa8, 0x0, 0x0, 0xf3, + 0x99, 0x0, 0x0, 0xf3, 0x7c, 0x0, 0x3, 0xf1, + 0x2f, 0xa4, 0x6d, 0xa0, 0x3, 0xcf, 0xe9, 0x0, + + /* U+0056 "V" */ + 0x1e, 0x0, 0x0, 0x6, 0xa0, 0xe5, 0x0, 0x0, + 0xc7, 0x8, 0xb0, 0x0, 0x2f, 0x10, 0x3f, 0x10, + 0x8, 0xc0, 0x0, 0xd6, 0x0, 0xd6, 0x0, 0x7, + 0xc0, 0x3f, 0x10, 0x0, 0x1f, 0x29, 0xa0, 0x0, + 0x0, 0xc8, 0xe5, 0x0, 0x0, 0x6, 0xff, 0x0, + 0x0, 0x0, 0x1e, 0x80, 0x0, + + /* U+0057 "W" */ + 0x6a, 0x0, 0x0, 0x2, 0xe0, 0x5d, 0x0, 0x0, + 0x4, 0xd0, 0x3f, 0x0, 0xc5, 0x6, 0xb0, 0x1f, + 0x12, 0xfb, 0x8, 0x90, 0xf, 0x37, 0xdf, 0xa, + 0x70, 0xd, 0x5c, 0x6d, 0x5c, 0x50, 0xa, 0x8f, + 0x18, 0xae, 0x30, 0x8, 0xfc, 0x3, 0xff, 0x10, + 0x6, 0xf7, 0x0, 0xef, 0x0, 0x3, 0xe1, 0x0, + 0x8c, 0x0, + + /* U+0058 "X" */ + 0x7a, 0x0, 0x1, 0xd3, 0x2f, 0x50, 0xa, 0xc0, + 0x7, 0xe0, 0x4f, 0x20, 0x0, 0xc9, 0xd8, 0x0, + 0x0, 0x2f, 0xd0, 0x0, 0x0, 0x4f, 0xe1, 0x0, + 0x0, 0xe6, 0xca, 0x0, 0x9, 0xc0, 0x2f, 0x40, + 0x4f, 0x20, 0x7, 0xe1, 0xa8, 0x0, 0x0, 0xc5, + + /* U+0059 "Y" */ + 0xd, 0x40, 0x0, 0xa, 0x70, 0x8d, 0x0, 0x4, + 0xf2, 0x0, 0xd8, 0x0, 0xe7, 0x0, 0x4, 0xf2, + 0x8d, 0x0, 0x0, 0xa, 0xdf, 0x40, 0x0, 0x0, + 0x1f, 0xa0, 0x0, 0x0, 0x0, 0xc6, 0x0, 0x0, + 0x0, 0xc, 0x60, 0x0, 0x0, 0x0, 0xc6, 0x0, + 0x0, 0x0, 0xb, 0x50, 0x0, + + /* U+005A "Z" */ + 0x6f, 0xff, 0xff, 0xf1, 0x3, 0x33, 0x3d, 0xa0, + 0x0, 0x0, 0x6e, 0x10, 0x0, 0x1, 0xf6, 0x0, + 0x0, 0xa, 0xc0, 0x0, 0x0, 0x5f, 0x20, 0x0, + 0x0, 0xe7, 0x0, 0x0, 0x9, 0xd0, 0x0, 0x0, + 0x3f, 0x63, 0x33, 0x30, 0x9f, 0xff, 0xff, 0xf3, + + /* U+005B "[" */ + 0x5f, 0xff, 0xb6, 0xc3, 0x32, 0x6c, 0x0, 0x6, + 0xc0, 0x0, 0x6c, 0x0, 0x6, 0xc0, 0x0, 0x6c, + 0x0, 0x6, 0xc0, 0x0, 0x6c, 0x0, 0x6, 0xc0, + 0x0, 0x6c, 0x0, 0x6, 0xc0, 0x0, 0x6c, 0x0, + 0x6, 0xff, 0xfb, 0x3, 0x33, 0x10, + + /* U+005C "\\" */ + 0x5c, 0x0, 0x0, 0x0, 0x1f, 0x30, 0x0, 0x0, + 0xb, 0x90, 0x0, 0x0, 0x5, 0xf0, 0x0, 0x0, + 0x0, 0xe5, 0x0, 0x0, 0x0, 0x9b, 0x0, 0x0, + 0x0, 0x3f, 0x10, 0x0, 0x0, 0xd, 0x70, 0x0, + 0x0, 0x7, 0xd0, 0x0, 0x0, 0x1, 0xf3, 0x0, + 0x0, 0x0, 0xb9, 0x0, 0x0, 0x0, 0x5e, 0x0, + 0x0, 0x0, 0xf, 0x50, 0x0, 0x0, 0x9, 0xb0, + 0x0, 0x0, 0x3, 0xe0, + + /* U+005D "]" */ + 0x2f, 0xff, 0xf0, 0x3, 0x35, 0xf0, 0x0, 0x2, + 0xf0, 0x0, 0x2, 0xf0, 0x0, 0x2, 0xf0, 0x0, + 0x2, 0xf0, 0x0, 0x2, 0xf0, 0x0, 0x2, 0xf0, + 0x0, 0x2, 0xf0, 0x0, 0x2, 0xf0, 0x0, 0x2, + 0xf0, 0x0, 0x2, 0xf0, 0x0, 0x2, 0xf0, 0x2f, + 0xff, 0xf0, 0x2, 0x33, 0x20, + + /* U+005E "^" */ + 0x0, 0xc, 0x60, 0x0, 0x4, 0xfe, 0x0, 0x0, + 0xc7, 0xd6, 0x0, 0x4f, 0x6, 0xd0, 0xb, 0x80, + 0xe, 0x51, 0xe1, 0x0, 0x7a, + + /* U+005F "_" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0xff, 0xff, + 0xff, 0xf0, 0x3, 0x33, 0x33, 0x33, 0x20, + + /* U+0060 "`" */ + 0x5d, 0x20, 0x1, 0xbf, 0x60, 0x0, 0x4d, 0x30, + + /* U+0061 "a" */ + 0x6, 0xcf, 0xea, 0x11, 0xd7, 0x44, 0xca, 0x0, + 0x0, 0x4, 0xd0, 0x8e, 0xfe, 0xce, 0x7e, 0x53, + 0x49, 0xeb, 0x80, 0x0, 0x6e, 0x9c, 0x22, 0x8f, + 0xe1, 0xaf, 0xfa, 0x4d, + + /* U+0062 "b" */ + 0x69, 0x0, 0x0, 0x0, 0x8a, 0x0, 0x0, 0x0, + 0x8a, 0x0, 0x0, 0x0, 0x8a, 0x6e, 0xfa, 0x10, + 0x8e, 0xd5, 0x5c, 0xd0, 0x8f, 0x10, 0x1, 0xf4, + 0x8b, 0x0, 0x0, 0xb7, 0x8b, 0x0, 0x0, 0xb7, + 0x8f, 0x10, 0x1, 0xf4, 0x8e, 0xd5, 0x5c, 0xd0, + 0x68, 0x6e, 0xfa, 0x10, + + /* U+0063 "c" */ + 0x2, 0xbf, 0xeb, 0x40, 0x1f, 0xb4, 0x59, 0xf2, + 0x9c, 0x0, 0x0, 0x0, 0xc7, 0x0, 0x0, 0x0, + 0xc7, 0x0, 0x0, 0x0, 0x9c, 0x0, 0x0, 0x20, + 0x2f, 0xb4, 0x59, 0xf4, 0x2, 0xbf, 0xfb, 0x40, + + /* U+0064 "d" */ + 0x0, 0x0, 0x0, 0xe0, 0x0, 0x0, 0x1, 0xf1, + 0x0, 0x0, 0x1, 0xf1, 0x5, 0xdf, 0xc3, 0xf1, + 0x3f, 0x84, 0x7e, 0xf1, 0xaa, 0x0, 0x7, 0xf1, + 0xd5, 0x0, 0x2, 0xf1, 0xd5, 0x0, 0x1, 0xf1, + 0xa9, 0x0, 0x6, 0xf1, 0x3f, 0x62, 0x5e, 0xf1, + 0x5, 0xdf, 0xc3, 0xe0, + + /* U+0065 "e" */ + 0x2, 0xbf, 0xea, 0x10, 0x2f, 0x94, 0x4b, 0xc0, + 0x9a, 0x0, 0x0, 0xe4, 0xcf, 0xff, 0xff, 0xf7, + 0xc8, 0x33, 0x33, 0x30, 0xaa, 0x0, 0x0, 0x0, + 0x3f, 0x94, 0x58, 0xe3, 0x4, 0xcf, 0xec, 0x60, + + /* U+0066 "f" */ + 0x0, 0x6, 0xdf, 0xd5, 0x0, 0x2f, 0x74, 0x76, + 0x0, 0x6c, 0x0, 0x0, 0x0, 0x8a, 0x0, 0x0, + 0x7f, 0xff, 0xff, 0xc0, 0x3, 0x9b, 0x33, 0x20, + 0x0, 0x8a, 0x0, 0x0, 0x0, 0x8a, 0x0, 0x0, + 0x0, 0x8a, 0x0, 0x0, 0x0, 0x8a, 0x0, 0x0, + 0x0, 0x69, 0x0, 0x0, + + /* U+0067 "g" */ + 0x5, 0xdf, 0xc3, 0xe0, 0x3f, 0x73, 0x6e, 0xf1, + 0xa9, 0x0, 0x6, 0xf1, 0xd5, 0x0, 0x1, 0xf1, + 0xd5, 0x0, 0x2, 0xf1, 0xaa, 0x0, 0x7, 0xf1, + 0x3f, 0x84, 0x7e, 0xf1, 0x5, 0xdf, 0xc4, 0xf1, + 0x0, 0x0, 0x2, 0xf0, 0x38, 0x54, 0x5d, 0xb0, + 0x3a, 0xef, 0xea, 0x10, + + /* U+0068 "h" */ + 0x5a, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, + 0x6c, 0x0, 0x0, 0x0, 0x6c, 0x1a, 0xfd, 0x30, + 0x6d, 0xd9, 0x4a, 0xe0, 0x6f, 0x70, 0x1, 0xf1, + 0x6e, 0x0, 0x0, 0xf2, 0x6c, 0x0, 0x0, 0xf2, + 0x6c, 0x0, 0x0, 0xf2, 0x6c, 0x0, 0x0, 0xf2, + 0x5a, 0x0, 0x0, 0xe1, + + /* U+0069 "i" */ + 0x0, 0xd, 0x80, 0x0, 0x0, 0xe, 0x80, 0x0, + 0x0, 0x2, 0x10, 0x0, 0xf, 0xff, 0x80, 0x0, + 0x2, 0x3a, 0x90, 0x0, 0x0, 0x9, 0x90, 0x0, + 0x0, 0x9, 0x90, 0x0, 0x0, 0x9, 0x90, 0x0, + 0x0, 0x9, 0x90, 0x0, 0x13, 0x3a, 0xa3, 0x31, + 0x7f, 0xff, 0xff, 0xf7, + + /* U+006A "j" */ + 0x0, 0x0, 0x5f, 0x0, 0x0, 0x6, 0xf0, 0x0, + 0x0, 0x2, 0x0, 0xdf, 0xff, 0xf0, 0x2, 0x33, + 0x4f, 0x10, 0x0, 0x1, 0xf1, 0x0, 0x0, 0x1f, + 0x10, 0x0, 0x1, 0xf1, 0x0, 0x0, 0x1f, 0x10, + 0x0, 0x1, 0xf1, 0x0, 0x0, 0x1f, 0x10, 0x0, + 0x2, 0xf0, 0x6e, 0x74, 0xac, 0x0, 0x6d, 0xfc, + 0x30, + + /* U+006B "k" */ + 0x2e, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x0, 0x0, + 0x3f, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x4, 0xe1, + 0x3f, 0x0, 0x5f, 0x70, 0x3f, 0x5, 0xf6, 0x0, + 0x3f, 0x6f, 0x80, 0x0, 0x3f, 0xfa, 0xe2, 0x0, + 0x3f, 0x40, 0xad, 0x10, 0x3f, 0x0, 0xc, 0xc0, + 0x2e, 0x0, 0x1, 0xd4, + + /* U+006C "l" */ + 0x3f, 0xff, 0x60, 0x0, 0x3, 0x3b, 0x80, 0x0, + 0x0, 0xa, 0x80, 0x0, 0x0, 0xa, 0x80, 0x0, + 0x0, 0xa, 0x80, 0x0, 0x0, 0xa, 0x80, 0x0, + 0x0, 0xa, 0x80, 0x0, 0x0, 0xa, 0x80, 0x0, + 0x0, 0xa, 0x80, 0x0, 0x13, 0x3b, 0x93, 0x30, + 0x8f, 0xff, 0xff, 0xf6, + + /* U+006D "m" */ + 0xd, 0x5e, 0xb2, 0xdd, 0x20, 0xfc, 0x3e, 0xd4, + 0xb8, 0xf, 0x50, 0xc9, 0x8, 0xa0, 0xf2, 0xc, + 0x70, 0x8a, 0xf, 0x20, 0xc6, 0x8, 0xa0, 0xf2, + 0xc, 0x60, 0x8a, 0xf, 0x20, 0xc6, 0x8, 0xa0, + 0xe1, 0xb, 0x50, 0x69, + + /* U+006E "n" */ + 0x59, 0x1b, 0xfd, 0x30, 0x6c, 0xe7, 0x38, 0xe0, + 0x6f, 0x60, 0x0, 0xf1, 0x6e, 0x0, 0x0, 0xf2, + 0x6c, 0x0, 0x0, 0xf2, 0x6c, 0x0, 0x0, 0xf2, + 0x6c, 0x0, 0x0, 0xf2, 0x5a, 0x0, 0x0, 0xe1, + + /* U+006F "o" */ + 0x3, 0xbf, 0xe9, 0x0, 0x2f, 0xa4, 0x5d, 0xb0, + 0xaa, 0x0, 0x1, 0xf4, 0xe4, 0x0, 0x0, 0xb7, + 0xe4, 0x0, 0x0, 0xb7, 0xaa, 0x0, 0x1, 0xf4, + 0x2f, 0x94, 0x5d, 0xb0, 0x3, 0xcf, 0xe9, 0x0, + + /* U+0070 "p" */ + 0x68, 0x7e, 0xfa, 0x10, 0x8f, 0xc4, 0x3b, 0xd0, + 0x8f, 0x0, 0x0, 0xf4, 0x8b, 0x0, 0x0, 0xb7, + 0x8b, 0x0, 0x0, 0xb7, 0x8f, 0x10, 0x1, 0xf4, + 0x8e, 0xd5, 0x5c, 0xd0, 0x8a, 0x6e, 0xfa, 0x10, + 0x8a, 0x0, 0x0, 0x0, 0x8a, 0x0, 0x0, 0x0, + 0x69, 0x0, 0x0, 0x0, + + /* U+0071 "q" */ + 0x5, 0xdf, 0xc3, 0xe0, 0x3f, 0x73, 0x6e, 0xf1, + 0xa9, 0x0, 0x6, 0xf1, 0xd5, 0x0, 0x2, 0xf1, + 0xd5, 0x0, 0x2, 0xf1, 0xaa, 0x0, 0x7, 0xf1, + 0x3f, 0x84, 0x7e, 0xf1, 0x5, 0xdf, 0xc3, 0xf1, + 0x0, 0x0, 0x1, 0xf1, 0x0, 0x0, 0x1, 0xf1, + 0x0, 0x0, 0x0, 0xe0, + + /* U+0072 "r" */ + 0x86, 0x8, 0xee, 0x59, 0x8b, 0xe8, 0x72, 0x9e, + 0xc0, 0x0, 0x9, 0xf2, 0x0, 0x0, 0x9b, 0x0, + 0x0, 0x9, 0x90, 0x0, 0x0, 0x99, 0x0, 0x0, + 0x8, 0x80, 0x0, 0x0, + + /* U+0073 "s" */ + 0x7, 0xef, 0xea, 0x40, 0x5f, 0x63, 0x5a, 0xb0, + 0x7c, 0x0, 0x0, 0x0, 0x2e, 0xeb, 0x96, 0x10, + 0x0, 0x57, 0x9d, 0xd0, 0x0, 0x0, 0x1, 0xf2, + 0x8d, 0x74, 0x4a, 0xe0, 0x17, 0xce, 0xfc, 0x30, + + /* U+0074 "t" */ + 0x0, 0xe, 0x10, 0x0, 0x0, 0x0, 0xf2, 0x0, + 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, 0xff, 0xff, + 0xff, 0xc0, 0x2, 0x3f, 0x53, 0x32, 0x0, 0x0, + 0xf2, 0x0, 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, + 0x0, 0xf3, 0x0, 0x0, 0x0, 0xc, 0xb4, 0x6d, + 0x70, 0x0, 0x3c, 0xfd, 0x70, + + /* U+0075 "u" */ + 0x78, 0x0, 0x1, 0xe0, 0x99, 0x0, 0x2, 0xf0, + 0x99, 0x0, 0x2, 0xf0, 0x99, 0x0, 0x2, 0xf0, + 0x99, 0x0, 0x5, 0xf0, 0x8a, 0x0, 0xc, 0xf0, + 0x5e, 0x43, 0xba, 0xf0, 0x8, 0xee, 0x70, 0xe0, + + /* U+0076 "v" */ + 0xd, 0x30, 0x0, 0x9, 0x70, 0xa9, 0x0, 0x1, + 0xf4, 0x4, 0xf1, 0x0, 0x7d, 0x0, 0xd, 0x70, + 0xd, 0x60, 0x0, 0x6e, 0x4, 0xf0, 0x0, 0x0, + 0xe5, 0xb9, 0x0, 0x0, 0x8, 0xdf, 0x20, 0x0, + 0x0, 0x1e, 0xa0, 0x0, + + /* U+0077 "w" */ + 0x79, 0x0, 0x0, 0x0, 0xe1, 0x5d, 0x0, 0x94, + 0x3, 0xe0, 0x1f, 0x11, 0xfa, 0x7, 0xb0, 0xd, + 0x45, 0xcf, 0xa, 0x70, 0xa, 0x8a, 0x6c, 0x4e, + 0x30, 0x6, 0xbf, 0x17, 0xbf, 0x0, 0x2, 0xfc, + 0x2, 0xfc, 0x0, 0x0, 0xd6, 0x0, 0xc7, 0x0, + + /* U+0078 "x" */ + 0x6b, 0x0, 0x2, 0xe2, 0x1d, 0x90, 0x1d, 0xa0, + 0x3, 0xf6, 0xbc, 0x0, 0x0, 0x5f, 0xe1, 0x0, + 0x0, 0x7f, 0xf2, 0x0, 0x4, 0xf4, 0x9d, 0x10, + 0x2e, 0x80, 0xc, 0xb0, 0x8a, 0x0, 0x1, 0xd3, + + /* U+0079 "y" */ + 0xd, 0x30, 0x0, 0x9, 0x70, 0xab, 0x0, 0x1, + 0xf3, 0x2, 0xf2, 0x0, 0x9c, 0x0, 0xb, 0xa0, + 0x1f, 0x40, 0x0, 0x3f, 0x28, 0xd0, 0x0, 0x0, + 0xba, 0xe5, 0x0, 0x0, 0x4, 0xfd, 0x0, 0x0, + 0x0, 0xf, 0x60, 0x0, 0x0, 0x6, 0xe0, 0x0, + 0x0, 0x0, 0xd7, 0x0, 0x0, 0x0, 0x2d, 0x0, + 0x0, 0x0, + + /* U+007A "z" */ + 0x5f, 0xff, 0xff, 0xf0, 0x3, 0x33, 0x5f, 0x90, + 0x0, 0x0, 0xcc, 0x0, 0x0, 0xa, 0xe1, 0x0, + 0x0, 0x7f, 0x30, 0x0, 0x4, 0xf5, 0x0, 0x0, + 0x2e, 0xb3, 0x33, 0x30, 0x8f, 0xff, 0xff, 0xf2, + + /* U+007B "{" */ + 0x0, 0x1, 0x9e, 0xa0, 0x0, 0xbd, 0x41, 0x0, + 0xf, 0x30, 0x0, 0x0, 0xf2, 0x0, 0x0, 0x1f, + 0x10, 0x0, 0x19, 0xb0, 0x0, 0x8f, 0xb0, 0x0, + 0x1, 0x4b, 0x90, 0x0, 0x0, 0x1f, 0x10, 0x0, + 0x0, 0xf2, 0x0, 0x0, 0xf, 0x20, 0x0, 0x0, + 0xf3, 0x0, 0x0, 0xc, 0xb2, 0x0, 0x0, 0x2c, + 0xfa, 0x0, 0x0, 0x1, 0x10, + + /* U+007C "|" */ + 0xb5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, + 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xb5, + + /* U+007D "}" */ + 0x1f, 0xd6, 0x0, 0x0, 0x3, 0x6f, 0x40, 0x0, + 0x0, 0x9, 0x90, 0x0, 0x0, 0x8, 0xa0, 0x0, + 0x0, 0x7, 0xa0, 0x0, 0x0, 0x2, 0xe4, 0x0, + 0x0, 0x0, 0x3e, 0xf2, 0x0, 0x1, 0xe7, 0x30, + 0x0, 0x7, 0xa0, 0x0, 0x0, 0x9, 0x90, 0x0, + 0x0, 0x8, 0xa0, 0x0, 0x0, 0x9, 0x90, 0x0, + 0x0, 0x4f, 0x50, 0x0, 0x1f, 0xf9, 0x0, 0x0, + 0x2, 0x0, 0x0, 0x0, + + /* U+007E "~" */ + 0x0, 0x0, 0x0, 0x0, 0x2d, 0xfc, 0x42, 0x93, + 0xa8, 0x5a, 0xff, 0xc0, 0x0, 0x0, 0x13, 0x0, + + /* U+00B0 "°" */ + 0x3, 0xde, 0x50, 0xd, 0x75, 0xf1, 0xf, 0x0, + 0xc4, 0xe, 0x52, 0xf2, 0x4, 0xff, 0x70, 0x0, + 0x1, 0x0, + + /* U+2022 "•" */ + 0x0, 0x32, 0x0, 0xef, 0xf8, 0xf, 0xff, 0x90, + 0xff, 0xf9, 0xc, 0xff, 0x60, + + /* U+E0B4 "" */ + 0x4, 0xf3, 0x8e, 0x20, 0x0, 0x8, 0xf6, 0xbf, + 0x40, 0x0, 0xaf, 0xff, 0xff, 0xc3, 0x0, 0xff, + 0xff, 0xff, 0xff, 0x40, 0xff, 0x0, 0x0, 0x9f, + 0xc0, 0xff, 0x0, 0x0, 0x3f, 0xf0, 0xff, 0x0, + 0x0, 0x9f, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x80, + 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff, 0x0, 0x0, + 0x7, 0xfd, 0xff, 0x0, 0x0, 0x0, 0xff, 0xff, + 0x0, 0x0, 0x7, 0xfd, 0xff, 0xff, 0xff, 0xff, + 0xf4, 0xaf, 0xff, 0xff, 0xfc, 0x30, 0x8, 0xf6, + 0xbf, 0x40, 0x0, 0x5, 0xf3, 0x8e, 0x20, 0x0, + + /* U+F001 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x49, 0xec, + 0x0, 0x0, 0x0, 0x0, 0x16, 0xbf, 0xff, 0xff, + 0x0, 0x0, 0x3, 0x8c, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, + 0x0, 0x0, 0xff, 0xff, 0xfe, 0xa5, 0x10, 0xff, + 0x0, 0x0, 0xff, 0xd8, 0x40, 0x0, 0x0, 0xff, + 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, + 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, + 0x0, 0x0, 0xff, 0x0, 0x0, 0x19, 0xee, 0xff, + 0x0, 0x0, 0xff, 0x0, 0x0, 0xaf, 0xff, 0xff, + 0x19, 0xee, 0xff, 0x0, 0x0, 0xff, 0xff, 0xff, + 0xaf, 0xff, 0xff, 0x0, 0x0, 0xaf, 0xff, 0xfa, + 0xff, 0xff, 0xff, 0x0, 0x0, 0x19, 0xee, 0x91, + 0xaf, 0xff, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x19, 0xee, 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F008 "" */ + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xf9, 0x9, 0xf3, 0x0, 0x0, 0x3f, 0x90, 0x9f, + 0xf9, 0x9, 0xf0, 0x0, 0x0, 0xf, 0x90, 0x9f, + 0xff, 0xff, 0xf0, 0x0, 0x0, 0xf, 0xff, 0xff, + 0xff, 0xff, 0xf3, 0x0, 0x0, 0x3f, 0xff, 0xff, + 0xf9, 0x9, 0xff, 0xff, 0xff, 0xff, 0x90, 0x9f, + 0xf9, 0x9, 0xff, 0xff, 0xff, 0xff, 0x90, 0x9f, + 0xff, 0xff, 0xf3, 0x0, 0x0, 0x3f, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x0, 0x0, 0xf, 0xff, 0xff, + 0xf9, 0x9, 0xf0, 0x0, 0x0, 0xf, 0x90, 0x9f, + 0xf9, 0x9, 0xf3, 0x0, 0x0, 0x3f, 0x90, 0x9f, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, + + /* U+F00B "" */ + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, + 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, + 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, + 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, + + /* U+F00C "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xcc, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1d, 0xfc, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xdf, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0xfd, 0x10, 0xcc, 0x10, 0x0, 0x1, + 0xdf, 0xd1, 0x0, 0xcf, 0xd1, 0x0, 0x1d, 0xfd, + 0x10, 0x0, 0x1d, 0xfd, 0x11, 0xdf, 0xd1, 0x0, + 0x0, 0x1, 0xdf, 0xdd, 0xfd, 0x10, 0x0, 0x0, + 0x0, 0x1d, 0xff, 0xd1, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xcc, 0x10, 0x0, 0x0, 0x0, + + /* U+F00D "" */ + 0xcc, 0x10, 0x0, 0x1, 0xcc, 0xcf, 0xd1, 0x0, + 0x1d, 0xfc, 0x1d, 0xfd, 0x11, 0xdf, 0xd1, 0x1, + 0xdf, 0xdd, 0xfd, 0x10, 0x0, 0x1d, 0xff, 0xd1, + 0x0, 0x0, 0x1d, 0xff, 0xd1, 0x0, 0x1, 0xdf, + 0xdd, 0xfd, 0x10, 0x1d, 0xfd, 0x11, 0xdf, 0xd1, + 0xcf, 0xd1, 0x0, 0x1d, 0xfc, 0xcc, 0x10, 0x0, + 0x1, 0xcc, + + /* U+F011 "" */ + 0x0, 0x0, 0x0, 0xb, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x10, 0xe, 0xf1, 0x1, 0x10, 0x0, + 0x0, 0x2e, 0xf0, 0xe, 0xf1, 0xc, 0xf4, 0x0, + 0x0, 0xdf, 0xb0, 0xe, 0xf1, 0x8, 0xff, 0x20, + 0x8, 0xfc, 0x0, 0xe, 0xf1, 0x0, 0xaf, 0xb0, + 0xe, 0xf3, 0x0, 0xe, 0xf1, 0x0, 0x1f, 0xf1, + 0x2f, 0xe0, 0x0, 0xe, 0xf1, 0x0, 0xb, 0xf5, + 0x3f, 0xc0, 0x0, 0xe, 0xf1, 0x0, 0x9, 0xf6, + 0x2f, 0xc0, 0x0, 0xb, 0xd0, 0x0, 0x9, 0xf5, + 0xf, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xf3, + 0xb, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xe0, + 0x4, 0xff, 0x30, 0x0, 0x0, 0x1, 0xef, 0x70, + 0x0, 0x8f, 0xf6, 0x0, 0x0, 0x5e, 0xfb, 0x0, + 0x0, 0x8, 0xff, 0xfc, 0xce, 0xff, 0xb0, 0x0, + 0x0, 0x0, 0x4b, 0xff, 0xff, 0xd6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0x31, 0x0, 0x0, 0x0, + + /* U+F013 "" */ + 0x0, 0x0, 0x0, 0xbf, 0xfb, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xff, 0xff, 0x10, 0x0, 0x0, + 0x0, 0x40, 0x8, 0xff, 0xff, 0x80, 0x4, 0x0, + 0x9, 0xff, 0xef, 0xff, 0xff, 0xfe, 0xff, 0x90, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x7f, 0xff, 0xff, 0xe9, 0x9e, 0xff, 0xff, 0xf7, + 0xb, 0xff, 0xfe, 0x10, 0x1, 0xef, 0xff, 0xb0, + 0x0, 0xff, 0xf9, 0x0, 0x0, 0x9f, 0xff, 0x0, + 0x0, 0xff, 0xf9, 0x0, 0x0, 0x9f, 0xff, 0x0, + 0xa, 0xff, 0xfe, 0x10, 0x1, 0xef, 0xff, 0xb0, + 0x7f, 0xff, 0xff, 0xe9, 0x9e, 0xff, 0xff, 0xf7, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x9, 0xff, 0xef, 0xff, 0xff, 0xfe, 0xff, 0x90, + 0x0, 0x40, 0x7, 0xff, 0xff, 0x70, 0x4, 0x0, + 0x0, 0x0, 0x1, 0xff, 0xff, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xbf, 0xfb, 0x0, 0x0, 0x0, + + /* U+F015 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0xc2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e, 0xff, + 0xe3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, + 0xff, 0xff, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6f, 0xff, 0xff, 0xff, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, + 0x0, 0x0, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfa, 0x0, 0x1, 0xcf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfb, 0x0, 0xcf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0xb, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x0, 0x0, 0xff, 0xff, 0xf3, 0x0, 0x3f, + 0xff, 0xff, 0x0, 0x0, 0xf, 0xff, 0xff, 0x0, + 0x0, 0xff, 0xff, 0xf0, 0x0, 0x0, 0xff, 0xff, + 0xf0, 0x0, 0xf, 0xff, 0xff, 0x0, 0x0, 0xf, + 0xff, 0xff, 0x0, 0x0, 0xff, 0xff, 0xf0, 0x0, + 0x0, 0xaf, 0xff, 0xa0, 0x0, 0xa, 0xff, 0xfa, + 0x0, 0x0, + + /* U+F019 "" */ + 0x0, 0x0, 0x0, 0xc, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xc1, 0xf, 0xf0, 0x1c, 0xc0, 0x0, + 0x0, 0xc, 0xfd, 0x1f, 0xf1, 0xdf, 0xc0, 0x0, + 0x0, 0x1, 0xdf, 0xdf, 0xfd, 0xfd, 0x10, 0x0, + 0x0, 0x0, 0x1d, 0xff, 0xff, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xdf, 0xfd, 0x10, 0x0, 0x0, + 0x4e, 0xff, 0xfa, 0x1c, 0xc1, 0xaf, 0xff, 0xe4, + 0xef, 0xff, 0xff, 0xb1, 0x1b, 0xff, 0xfd, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, 0xdf, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfe, + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, + + /* U+F01C "" */ + 0x0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x0, + 0x2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, + 0x6, 0xfa, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x60, + 0xa, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xa0, + 0xe, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xe0, + 0x2f, 0xe0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xf2, + 0x6f, 0xa0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xf6, + 0xaf, 0x60, 0x0, 0x0, 0x0, 0x0, 0x6, 0xfa, + 0xef, 0xff, 0xa0, 0x0, 0x0, 0xa, 0xff, 0xfe, + 0xff, 0xff, 0xf5, 0x0, 0x0, 0x5f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, + + /* U+F021 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3a, 0xdf, 0xeb, 0x40, 0xb, 0xd0, + 0x0, 0x9, 0xff, 0xff, 0xff, 0xfb, 0x1e, 0xf1, + 0x0, 0xbf, 0xf7, 0x20, 0x16, 0xef, 0xdf, 0xf1, + 0x7, 0xfe, 0x20, 0x0, 0x0, 0x1c, 0xff, 0xf1, + 0xe, 0xf4, 0x0, 0x0, 0xb, 0xff, 0xff, 0xf1, + 0xc, 0xa0, 0x0, 0x0, 0xb, 0xff, 0xff, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7f, 0xff, 0xfe, 0x20, 0x0, 0x0, 0x5e, 0x30, + 0xbf, 0xff, 0xfe, 0x20, 0x0, 0x0, 0xef, 0x40, + 0xbf, 0xff, 0x40, 0x0, 0x0, 0xa, 0xfc, 0x0, + 0xbf, 0xdf, 0xf9, 0x20, 0x15, 0xdf, 0xe2, 0x0, + 0xbf, 0x47, 0xff, 0xff, 0xff, 0xfd, 0x20, 0x0, + 0x8e, 0x20, 0x29, 0xdf, 0xec, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F026 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xcb, 0x0, 0x0, 0x0, 0x2e, 0xff, 0x0, + 0x0, 0x4, 0xff, 0xff, 0x0, 0x0, 0x5f, 0xff, + 0xff, 0x4e, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, + 0xff, 0xff, 0x4e, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x5f, 0xff, 0xff, 0x0, 0x0, 0x4, 0xff, + 0xff, 0x0, 0x0, 0x0, 0x2e, 0xff, 0x0, 0x0, + 0x0, 0x1, 0xcb, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F027 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xcb, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2e, 0xff, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x5f, 0xff, + 0xff, 0x0, 0x0, 0x4e, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x60, 0xef, 0xff, 0xff, 0xff, 0xff, 0x3, + 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xae, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xae, 0xef, + 0xff, 0xff, 0xff, 0xff, 0x3, 0xf8, 0x4e, 0xff, + 0xff, 0xff, 0xff, 0x0, 0x60, 0x0, 0x0, 0x5f, + 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, + 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xcb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F028 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xcb, 0x0, + 0x0, 0x6, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x2e, + 0xff, 0x0, 0x0, 0x1, 0xde, 0x20, 0x0, 0x0, + 0x4, 0xff, 0xff, 0x0, 0x3, 0xb1, 0x1e, 0xb0, + 0x0, 0x0, 0x5f, 0xff, 0xff, 0x0, 0x2, 0xfc, + 0x6, 0xf3, 0x4e, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x60, 0x4f, 0x60, 0xf9, 0xef, 0xff, 0xff, 0xff, + 0xff, 0x3, 0xf8, 0xc, 0xc0, 0xad, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0, 0xae, 0x9, 0xf0, 0x8f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xae, 0x9, + 0xf0, 0x8f, 0xef, 0xff, 0xff, 0xff, 0xff, 0x3, + 0xf8, 0xc, 0xc0, 0xad, 0x4e, 0xff, 0xff, 0xff, + 0xff, 0x0, 0x60, 0x4f, 0x60, 0xf9, 0x0, 0x0, + 0x5f, 0xff, 0xff, 0x0, 0x2, 0xfc, 0x6, 0xf3, + 0x0, 0x0, 0x4, 0xff, 0xff, 0x0, 0x3, 0xb1, + 0x1e, 0xb0, 0x0, 0x0, 0x0, 0x2e, 0xff, 0x0, + 0x0, 0x1, 0xdf, 0x20, 0x0, 0x0, 0x0, 0x1, + 0xcb, 0x0, 0x0, 0x6, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F03E "" */ + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xff, 0x70, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x70, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xc1, 0xcf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x20, 0x2f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf6, 0x0, 0x6, 0xff, 0xff, + 0xff, 0xfe, 0x28, 0xb0, 0x0, 0x0, 0xbf, 0xff, + 0xff, 0xf3, 0x0, 0x10, 0x0, 0x0, 0x1e, 0xff, + 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, 0x5, 0xff, + 0xff, 0x20, 0x0, 0x0, 0x0, 0x0, 0x2, 0xff, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, + + /* U+F043 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x5f, 0xfc, + 0x0, 0x0, 0x0, 0x1, 0xef, 0xff, 0x60, 0x0, + 0x0, 0x9, 0xff, 0xff, 0xf1, 0x0, 0x0, 0x2f, + 0xff, 0xff, 0xf9, 0x0, 0x0, 0xaf, 0xff, 0xff, + 0xff, 0x20, 0x3, 0xff, 0xff, 0xff, 0xff, 0xa0, + 0xa, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xf, 0xff, + 0xff, 0xff, 0xff, 0xf7, 0x3f, 0xd8, 0xff, 0xff, + 0xff, 0xfa, 0x3f, 0xd2, 0xff, 0xff, 0xff, 0xfa, + 0xf, 0xf3, 0x8f, 0xff, 0xff, 0xf6, 0x8, 0xfe, + 0x32, 0x8f, 0xff, 0xe0, 0x0, 0xbf, 0xfd, 0xdf, + 0xff, 0x30, 0x0, 0x8, 0xff, 0xff, 0xc2, 0x0, + 0x0, 0x0, 0x3, 0x31, 0x0, 0x0, + + /* U+F048 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, 0x0, 0x0, + 0x2, 0xcb, 0xff, 0x0, 0x0, 0x3e, 0xff, 0xff, + 0x0, 0x6, 0xff, 0xff, 0xff, 0x0, 0x8f, 0xff, + 0xff, 0xff, 0xb, 0xff, 0xff, 0xff, 0xff, 0xdf, + 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xb, 0xff, 0xff, 0xff, 0xff, 0x0, 0x8f, + 0xff, 0xff, 0xff, 0x0, 0x6, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x3e, 0xff, 0xcc, 0x0, 0x0, 0x2, + 0xcb, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F04B "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8e, 0xa1, + 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x60, 0x0, + 0x0, 0x0, 0xff, 0xff, 0xfc, 0x30, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xf9, 0x10, 0x0, 0xff, 0xff, + 0xff, 0xff, 0xe5, 0x0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xc2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc2, 0xff, 0xff, 0xff, 0xff, + 0xe5, 0x0, 0xff, 0xff, 0xff, 0xf9, 0x10, 0x0, + 0xff, 0xff, 0xfc, 0x30, 0x0, 0x0, 0xff, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x8f, 0xa1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F04C "" */ + 0x8f, 0xf8, 0x0, 0x8f, 0xf8, 0xff, 0xff, 0x0, + 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, + 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, + 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, + 0x0, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, + 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0x0, + 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0x8f, + 0xf8, 0x0, 0x8f, 0xf8, + + /* U+F04D "" */ + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xef, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x4e, 0xff, 0xff, 0xff, 0xff, 0xe4, + + /* U+F051 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0xbd, 0x20, 0x0, + 0x0, 0xcc, 0xff, 0xe4, 0x0, 0x0, 0xff, 0xff, + 0xff, 0x60, 0x0, 0xff, 0xff, 0xff, 0xf9, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xb1, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, + 0xff, 0xff, 0xff, 0xb1, 0xff, 0xff, 0xff, 0xf9, + 0x0, 0xff, 0xff, 0xff, 0x60, 0x0, 0xff, 0xff, + 0xe4, 0x0, 0x0, 0xff, 0xbd, 0x20, 0x0, 0x0, + 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F052 "" */ + 0x0, 0x0, 0x0, 0x2d, 0xd2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xef, 0xfe, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0xff, 0xff, 0xd1, 0x0, 0x0, + 0x0, 0x0, 0xdf, 0xff, 0xff, 0xfc, 0x0, 0x0, + 0x0, 0xc, 0xff, 0xff, 0xff, 0xff, 0xb0, 0x0, + 0x0, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x0, + 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, + 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, + + /* U+F053 "" */ + 0x0, 0x0, 0x1, 0xcc, 0x0, 0x0, 0x1d, 0xfc, + 0x0, 0x1, 0xdf, 0xd1, 0x0, 0x1d, 0xfd, 0x10, + 0x1, 0xdf, 0xd1, 0x0, 0x1d, 0xfd, 0x10, 0x0, + 0xcf, 0xd1, 0x0, 0x0, 0xcf, 0xd1, 0x0, 0x0, + 0x1d, 0xfd, 0x10, 0x0, 0x1, 0xdf, 0xd1, 0x0, + 0x0, 0x1d, 0xfd, 0x10, 0x0, 0x1, 0xdf, 0xd1, + 0x0, 0x0, 0x1d, 0xfc, 0x0, 0x0, 0x1, 0xcc, + + /* U+F054 "" */ + 0xcc, 0x10, 0x0, 0x0, 0xcf, 0xd1, 0x0, 0x0, + 0x1d, 0xfd, 0x10, 0x0, 0x1, 0xdf, 0xd1, 0x0, + 0x0, 0x1d, 0xfd, 0x10, 0x0, 0x1, 0xdf, 0xd1, + 0x0, 0x0, 0x1d, 0xfc, 0x0, 0x0, 0x1d, 0xfc, + 0x0, 0x1, 0xdf, 0xd1, 0x0, 0x1d, 0xfd, 0x10, + 0x1, 0xdf, 0xd1, 0x0, 0x1d, 0xfd, 0x10, 0x0, + 0xcf, 0xd1, 0x0, 0x0, 0xcc, 0x10, 0x0, 0x0, + + /* U+F067 "" */ + 0x0, 0x0, 0x0, 0xcc, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, + 0x0, 0x0, 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf4, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf4, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, + 0x0, 0x0, 0x0, + + /* U+F068 "" */ + 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x4f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, + + /* U+F06E "" */ + 0x0, 0x0, 0x0, 0x28, 0xdf, 0xfd, 0x82, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x9, 0xff, 0xff, 0xff, + 0xff, 0x90, 0x0, 0x0, 0x0, 0x1, 0xdf, 0xff, + 0xc8, 0x8c, 0xff, 0xfd, 0x10, 0x0, 0x0, 0x1d, + 0xff, 0xe4, 0x0, 0x0, 0x4e, 0xff, 0xd1, 0x0, + 0x0, 0xbf, 0xff, 0x40, 0x2, 0xe8, 0x4, 0xff, + 0xfb, 0x0, 0x5, 0xff, 0xfc, 0x0, 0x1, 0xff, + 0x80, 0xcf, 0xff, 0x50, 0xd, 0xff, 0xf8, 0x1, + 0x1b, 0xff, 0xe0, 0x8f, 0xff, 0xd0, 0xd, 0xff, + 0xf8, 0xe, 0xff, 0xff, 0xe0, 0x8f, 0xff, 0xd0, + 0x5, 0xff, 0xfc, 0x8, 0xff, 0xff, 0x80, 0xcf, + 0xff, 0x50, 0x0, 0xbf, 0xff, 0x40, 0x8e, 0xe8, + 0x4, 0xff, 0xfb, 0x0, 0x0, 0x1d, 0xff, 0xe4, + 0x0, 0x0, 0x4e, 0xff, 0xd1, 0x0, 0x0, 0x1, + 0xdf, 0xff, 0xc8, 0x8c, 0xff, 0xfd, 0x10, 0x0, + 0x0, 0x0, 0x9, 0xff, 0xff, 0xff, 0xff, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x28, 0xdf, 0xfd, + 0x82, 0x0, 0x0, 0x0, + + /* U+F070 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xfc, + 0x10, 0x3, 0x9d, 0xff, 0xd8, 0x20, 0x0, 0x0, + 0x0, 0x0, 0x4f, 0xe5, 0xaf, 0xff, 0xff, 0xff, + 0xf9, 0x0, 0x0, 0x0, 0x0, 0x2, 0xdf, 0xff, + 0xfc, 0x88, 0xcf, 0xff, 0xd1, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xff, 0x50, 0x0, 0x4, 0xef, 0xfd, + 0x10, 0x0, 0x0, 0x9, 0x30, 0x6f, 0xd2, 0x2e, + 0x80, 0x4f, 0xff, 0xb0, 0x0, 0x0, 0x5f, 0xf6, + 0x3, 0xef, 0x7f, 0xf8, 0xc, 0xff, 0xf5, 0x0, + 0x0, 0xdf, 0xff, 0x60, 0x1c, 0xff, 0xfe, 0x8, + 0xff, 0xfd, 0x0, 0x0, 0xdf, 0xff, 0x80, 0x0, + 0x9f, 0xfe, 0x8, 0xff, 0xfd, 0x0, 0x0, 0x5f, + 0xff, 0xc0, 0x0, 0x5, 0xfe, 0x3c, 0xff, 0xf5, + 0x0, 0x0, 0xb, 0xff, 0xf4, 0x0, 0x0, 0x2d, + 0xff, 0xff, 0xb0, 0x0, 0x0, 0x1, 0xdf, 0xfe, + 0x40, 0x0, 0x1, 0xbf, 0xfd, 0x10, 0x0, 0x0, + 0x0, 0x1d, 0xff, 0xfc, 0x88, 0xb2, 0x7, 0xfd, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xff, 0xff, + 0xff, 0x50, 0x4e, 0xe4, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x8d, 0xfe, 0xc9, 0x20, 0x2, 0xcf, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F071 "" */ + 0x0, 0x0, 0x0, 0x1, 0xcd, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x9, 0xff, 0x90, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xff, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xff, + 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xff, + 0x66, 0xff, 0x50, 0x0, 0x0, 0x0, 0x0, 0xe, + 0xff, 0x44, 0xff, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0x8f, 0xff, 0x44, 0xff, 0xf8, 0x0, 0x0, 0x0, + 0x2, 0xff, 0xff, 0x44, 0xff, 0xff, 0x20, 0x0, + 0x0, 0xb, 0xff, 0xff, 0x66, 0xff, 0xff, 0xb0, + 0x0, 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf4, 0x0, 0x0, 0xdf, 0xff, 0xff, 0x33, 0xff, + 0xff, 0xfd, 0x0, 0x7, 0xff, 0xff, 0xff, 0x33, + 0xff, 0xff, 0xff, 0x70, 0xe, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe0, 0xa, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, + + /* U+F074 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbc, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xd1, + 0xcf, 0xfe, 0x80, 0x0, 0x9, 0xef, 0xff, 0xfc, + 0xcf, 0xff, 0xfa, 0x0, 0xaf, 0xff, 0xff, 0xfc, + 0x0, 0x3, 0xff, 0x63, 0xff, 0x30, 0xff, 0xd1, + 0x0, 0x0, 0x5f, 0xf2, 0x95, 0x0, 0xbc, 0x10, + 0x0, 0x0, 0xa, 0xfd, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xdf, 0x90, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x59, 0x2f, 0xf5, 0x0, 0xbc, 0x10, + 0x0, 0x3, 0xff, 0x36, 0xff, 0x30, 0xff, 0xd1, + 0xcf, 0xff, 0xfa, 0x0, 0xaf, 0xff, 0xff, 0xfc, + 0xcf, 0xfe, 0x90, 0x0, 0x9, 0xef, 0xff, 0xfc, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbc, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F077 "" */ + 0x0, 0x0, 0x1, 0xcc, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0xff, 0xd1, 0x0, 0x0, 0x0, 0x1, + 0xdf, 0xdd, 0xfd, 0x10, 0x0, 0x0, 0x1d, 0xfd, + 0x11, 0xdf, 0xd1, 0x0, 0x1, 0xdf, 0xd1, 0x0, + 0x1d, 0xfd, 0x10, 0x1d, 0xfd, 0x10, 0x0, 0x1, + 0xdf, 0xd1, 0xcf, 0xd1, 0x0, 0x0, 0x0, 0x1d, + 0xfc, 0xcc, 0x10, 0x0, 0x0, 0x0, 0x1, 0xcc, + + /* U+F078 "" */ + 0xcc, 0x10, 0x0, 0x0, 0x0, 0x1, 0xcc, 0xcf, + 0xd1, 0x0, 0x0, 0x0, 0x1d, 0xfc, 0x1d, 0xfd, + 0x10, 0x0, 0x1, 0xdf, 0xd1, 0x1, 0xdf, 0xd1, + 0x0, 0x1d, 0xfd, 0x10, 0x0, 0x1d, 0xfd, 0x11, + 0xdf, 0xd1, 0x0, 0x0, 0x1, 0xdf, 0xdd, 0xfd, + 0x10, 0x0, 0x0, 0x0, 0x1d, 0xff, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xcc, 0x10, 0x0, 0x0, + + /* U+F079 "" */ + 0x0, 0x1c, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xdf, 0xfd, 0x10, 0x4, 0xff, + 0xff, 0xe8, 0x0, 0x0, 0xc, 0xff, 0xff, 0xc0, + 0x4, 0xff, 0xff, 0xff, 0x80, 0x0, 0xb, 0xff, + 0xff, 0xb0, 0x0, 0x0, 0x0, 0x3f, 0xe0, 0x0, + 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xf, + 0xf0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xf0, 0x0, 0x0, 0xf, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0xf, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, + 0x0, 0xe, 0xf3, 0x0, 0x0, 0x0, 0xb, 0xff, + 0xff, 0xb0, 0x0, 0x8, 0xff, 0xff, 0xff, 0x40, + 0xc, 0xff, 0xff, 0xc0, 0x0, 0x0, 0x8e, 0xff, + 0xff, 0x40, 0x1, 0xdf, 0xfd, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xc1, 0x0, + + /* U+F07B "" */ + 0x4e, 0xff, 0xff, 0xc1, 0x0, 0x0, 0x0, 0x0, + 0xef, 0xff, 0xff, 0xfe, 0x30, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, + + /* U+F093 "" */ + 0x0, 0x0, 0x0, 0x1c, 0xc1, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xdf, 0xfd, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0xff, 0xff, 0xd1, 0x0, 0x0, + 0x0, 0x1, 0xdf, 0xdf, 0xfd, 0xfd, 0x10, 0x0, + 0x0, 0xc, 0xfd, 0x1f, 0xf1, 0xdf, 0xc0, 0x0, + 0x0, 0xc, 0xc1, 0xf, 0xf0, 0x1c, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, + 0x4e, 0xff, 0xff, 0x1c, 0xc1, 0xff, 0xff, 0xe4, + 0xef, 0xff, 0xff, 0xb1, 0x1b, 0xff, 0xfd, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, 0xdf, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xfe, + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, + + /* U+F095 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6a, 0xed, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xff, 0xf7, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xff, 0xff, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xef, 0xff, 0xff, 0x40, 0x0, 0x0, + 0x0, 0x0, 0xc, 0xff, 0xff, 0xf6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8f, 0xff, 0xfa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xff, 0xfb, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xd, 0xff, 0xf2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xff, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xff, + 0xa0, 0x0, 0x6, 0x40, 0x0, 0x0, 0x2, 0xff, + 0xff, 0xc2, 0xa, 0xff, 0xd7, 0x10, 0x0, 0x4, + 0xff, 0xff, 0xfb, 0xff, 0xff, 0xfd, 0x0, 0x0, + 0x4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x0, + 0x0, 0x2, 0xcf, 0xff, 0xff, 0xff, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x6d, 0xff, 0xff, 0xff, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x3, 0x8c, 0xef, 0xc0, + 0x0, + + /* U+F0C4 "" */ + 0x4, 0xcf, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4f, 0xff, 0xff, 0x40, 0x0, 0x0, 0x7f, 0xf6, + 0xcf, 0x70, 0x7f, 0xc0, 0x0, 0x8, 0xff, 0xf7, + 0xff, 0x0, 0xf, 0xf0, 0x0, 0x8f, 0xff, 0x80, + 0xcf, 0x70, 0x7f, 0xd0, 0x8, 0xff, 0xf8, 0x0, + 0x4f, 0xff, 0xff, 0xf7, 0x8f, 0xff, 0x80, 0x0, + 0x4, 0xcf, 0xdf, 0xff, 0xff, 0xf8, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xff, 0xff, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xff, 0xf8, 0x10, 0x0, 0x0, + 0x4, 0xcf, 0xdf, 0xff, 0x82, 0xe7, 0x0, 0x0, + 0x4f, 0xff, 0xff, 0xf8, 0x1e, 0xff, 0x70, 0x0, + 0xcf, 0x70, 0x7f, 0xd0, 0x7, 0xff, 0xf7, 0x0, + 0xff, 0x0, 0xf, 0xf0, 0x0, 0x7f, 0xff, 0x70, + 0xcf, 0x70, 0x7f, 0xc0, 0x0, 0x7, 0xff, 0xf7, + 0x4f, 0xff, 0xff, 0x40, 0x0, 0x0, 0x7f, 0xf6, + 0x4, 0xcf, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F0C5 "" */ + 0x0, 0x0, 0x4, 0xef, 0xff, 0xff, 0xff, 0xe4, + 0x0, 0x0, 0xe, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x4e, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xef, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0, 0xe, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xff, 0x0, 0x4, 0xef, 0xff, 0xff, 0xff, 0xe4, + 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, + 0xff, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x0, 0x0, + 0x4e, 0xff, 0xff, 0xff, 0xfe, 0x40, 0x0, 0x0, + + /* U+F0C7 "" */ + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xb1, 0x0, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0x10, 0xff, 0x30, + 0x0, 0x0, 0x3, 0xff, 0xd1, 0xff, 0x0, 0x0, + 0x0, 0x0, 0xff, 0xfb, 0xff, 0x0, 0x0, 0x0, + 0x0, 0xff, 0xff, 0xff, 0x30, 0x0, 0x0, 0x3, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfb, 0x11, 0xbf, 0xff, 0xff, 0xff, + 0xff, 0xf1, 0x0, 0x1f, 0xff, 0xff, 0xff, 0xff, + 0xf1, 0x0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0x11, 0xbf, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0x4e, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe4, + + /* U+F0C9 "" */ + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xcf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xcf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfc, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0xcf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, + + /* U+F0E0 "" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x25, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x52, + 0xf6, 0x2d, 0xff, 0xff, 0xff, 0xff, 0xd2, 0x6f, + 0xff, 0xa1, 0xaf, 0xff, 0xff, 0xfa, 0x1a, 0xff, + 0xff, 0xfd, 0x26, 0xff, 0xff, 0x62, 0xdf, 0xff, + 0xff, 0xff, 0xf6, 0x2c, 0xc2, 0x6f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xa1, 0x1a, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, + + /* U+F0E7 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1c, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0xef, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0x4f, 0xff, 0x70, 0x0, 0x0, 0x0, 0x6, 0xff, + 0xff, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, 0xf9, + 0x0, 0x0, 0x0, 0xa, 0xff, 0xff, 0xf2, 0x0, + 0x0, 0x0, 0xbf, 0xff, 0xff, 0xb0, 0x0, 0x0, + 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, 0xb, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0, 0x0, + 0xb, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, 0x2f, + 0xff, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x9f, 0xff, + 0xf8, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x60, + 0x0, 0x0, 0x0, 0x6, 0xff, 0xf4, 0x0, 0x0, + 0x0, 0x0, 0xd, 0xfe, 0x30, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F0EA "" */ + 0x0, 0x4, 0xdd, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x8f, 0xff, 0x99, 0xff, 0xf8, 0x0, 0x0, 0x0, + 0xff, 0xff, 0x99, 0xff, 0xff, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xd4, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0x48, 0xff, 0xff, 0x7, 0x0, + 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xf, 0x70, + 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xf, 0xf7, + 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0x30, 0x0, + 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, + 0x8f, 0xff, 0xff, 0xf, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x8, 0xff, 0xff, 0xff, 0xf8, + + /* U+F0F3 "" */ + 0x0, 0x0, 0x0, 0xc, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3f, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0xff, 0xff, 0xc1, 0x0, 0x0, + 0x0, 0x1, 0xef, 0xff, 0xff, 0xfe, 0x10, 0x0, + 0x0, 0x8, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0, + 0x0, 0xe, 0xff, 0xff, 0xff, 0xff, 0xd0, 0x0, + 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, + 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, + 0x0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x0, + 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, + 0x2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, + 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xef, 0xfe, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4e, 0xe4, 0x0, 0x0, 0x0, + + /* U+F11C "" */ + 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe4, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0xff, 0x11, 0xf1, 0x1f, 0x11, 0xf1, + 0x1f, 0x11, 0xff, 0xff, 0x11, 0xf1, 0x1f, 0x11, + 0xf1, 0x1f, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, 0xf1, + 0x1f, 0x11, 0xf1, 0x1f, 0x11, 0xff, 0xff, 0x11, + 0xf1, 0x1f, 0x11, 0xf1, 0x1f, 0x11, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x11, 0xf1, 0x0, 0x0, 0x0, 0x1f, 0x11, + 0xff, 0xff, 0x11, 0xf1, 0x0, 0x0, 0x0, 0x1f, + 0x11, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0x4e, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe4, + + /* U+F124 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x71, 0x0, + 0x0, 0x0, 0x0, 0x5, 0xcf, 0xf7, 0x0, 0x0, + 0x0, 0x28, 0xef, 0xff, 0xf2, 0x0, 0x0, 0x5b, + 0xff, 0xff, 0xff, 0xc0, 0x1, 0x7e, 0xff, 0xff, + 0xff, 0xff, 0x50, 0x4f, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xf2, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xff, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0xff, 0x50, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, + 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x40, + 0x0, 0x0, + + /* U+F158 "" */ + 0x0, 0xcf, 0xff, 0xff, 0xe8, 0x0, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xc0, 0x0, 0xff, 0x0, 0x0, + 0x3d, 0xf8, 0x0, 0xff, 0x0, 0x0, 0x4, 0xfd, + 0x0, 0xff, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, + 0x0, 0x0, 0x4, 0xfd, 0x0, 0xff, 0x0, 0x0, + 0x3d, 0xf8, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xd0, + 0xcf, 0xff, 0xff, 0xff, 0xe8, 0x0, 0x0, 0xff, + 0x0, 0x0, 0x0, 0x0, 0xcf, 0xff, 0xff, 0xff, + 0xfc, 0x0, 0xcf, 0xff, 0xff, 0xff, 0xfc, 0x0, + 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcc, + 0x0, 0x0, 0x0, 0x0, + + /* U+F1EB "" */ + 0x0, 0x0, 0x3, 0x8b, 0xdf, 0xfd, 0xb8, 0x30, + 0x0, 0x0, 0x0, 0x5, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0x50, 0x0, 0x1, 0xcf, 0xfe, 0x94, + 0x20, 0x2, 0x49, 0xef, 0xfc, 0x10, 0x4e, 0xfe, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x6, 0xef, 0xe4, + 0xef, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xfe, 0x66, 0x0, 0x0, 0x49, 0xdf, 0xfd, + 0x94, 0x0, 0x0, 0x66, 0x0, 0x0, 0x2c, 0xff, + 0xff, 0xff, 0xff, 0xc2, 0x0, 0x0, 0x0, 0x1, + 0xff, 0xe7, 0x30, 0x3, 0x7e, 0xff, 0x20, 0x0, + 0x0, 0x2, 0xea, 0x0, 0x0, 0x0, 0x0, 0xae, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4e, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xef, 0xfe, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xef, 0xfe, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0xe4, + 0x0, 0x0, 0x0, 0x0, + + /* U+F240 "" */ + 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0x20, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb0, 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xf0, 0xff, 0xf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf, 0xfc, 0xff, 0xf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf, 0xff, 0xff, 0xf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0xfc, 0xff, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xf0, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xb0, 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfb, 0x20, + + /* U+F241 "" */ + 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0x20, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb0, 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xf0, 0xff, 0xf, 0xff, 0xff, 0xff, + 0xf0, 0x0, 0xf, 0xfc, 0xff, 0xf, 0xff, 0xff, + 0xff, 0xf0, 0x0, 0xf, 0xff, 0xff, 0xf, 0xff, + 0xff, 0xff, 0xf0, 0x0, 0xf, 0xff, 0xff, 0xf, + 0xff, 0xff, 0xff, 0xf0, 0x0, 0xf, 0xfc, 0xff, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xf0, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xb0, 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfb, 0x20, + + /* U+F242 "" */ + 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0x20, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb0, 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xf0, 0xff, 0xf, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0xf, 0xfc, 0xff, 0xf, 0xff, 0xff, + 0xf0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xf, 0xff, + 0xff, 0xf0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xf, + 0xff, 0xff, 0xf0, 0x0, 0x0, 0xf, 0xfc, 0xff, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xf0, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xb0, 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfb, 0x20, + + /* U+F243 "" */ + 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0x20, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb0, 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xf0, 0xff, 0xf, 0xff, 0x0, 0x0, + 0x0, 0x0, 0xf, 0xfc, 0xff, 0xf, 0xff, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xf, 0xff, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xf, + 0xff, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfc, 0xff, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xf0, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xb0, 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfb, 0x20, + + /* U+F244 "" */ + 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, + 0x20, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb0, 0xff, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1f, 0xf0, 0xff, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0xfc, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xfc, 0xff, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xf0, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xb0, 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfb, 0x20, + + /* U+F287 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xaf, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3d, 0xff, 0xff, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xd, 0x72, 0xbf, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xd0, 0x0, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x4e, 0xe6, 0x0, + 0xd6, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0xf, + 0xff, 0xf6, 0x9f, 0x55, 0x55, 0x55, 0x55, 0x5a, + 0xfb, 0x21, 0xff, 0xff, 0xdc, 0xcd, 0xfc, 0xcc, + 0xcc, 0xcc, 0xef, 0xf8, 0xa, 0xff, 0xc0, 0x0, + 0xc, 0x70, 0x0, 0x0, 0x7, 0xc3, 0x0, 0x5, + 0x50, 0x0, 0x0, 0x3e, 0x10, 0x23, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xba, 0x1e, + 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xcf, 0xff, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, 0x60, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x12, + 0x20, 0x0, 0x0, + + /* U+F293 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, + 0xdf, 0xfe, 0x92, 0x0, 0x2, 0xef, 0xfc, 0xef, + 0xff, 0x40, 0xd, 0xff, 0xfa, 0x2e, 0xff, 0xe0, + 0x4f, 0xff, 0xfa, 0x3, 0xff, 0xf5, 0x9f, 0xfa, + 0xfa, 0x35, 0x4f, 0xfa, 0xdf, 0xc0, 0x8a, 0x3d, + 0xb, 0xfd, 0xef, 0xfb, 0x3, 0x11, 0x8f, 0xfe, + 0xff, 0xff, 0xb0, 0x6, 0xff, 0xff, 0xff, 0xff, + 0xe1, 0x8, 0xff, 0xff, 0xef, 0xfe, 0x11, 0x10, + 0x9f, 0xff, 0xdf, 0xe1, 0x59, 0x3b, 0xb, 0xfd, + 0xaf, 0xd6, 0xfa, 0x38, 0x1d, 0xfb, 0x5f, 0xff, + 0xfa, 0x1, 0xdf, 0xf7, 0xd, 0xff, 0xfa, 0x1d, + 0xff, 0xf1, 0x3, 0xef, 0xfc, 0xdf, 0xff, 0x50, + 0x0, 0x18, 0xdf, 0xfe, 0xa3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+F2ED "" */ + 0x0, 0x0, 0xaf, 0xff, 0xfa, 0x0, 0x0, 0xcf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xcf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0xf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0xf, 0xf9, 0x9f, 0x99, 0xf9, 0x9f, + 0xf0, 0xf, 0xf8, 0x8f, 0x88, 0xf8, 0x8f, 0xf0, + 0xf, 0xf8, 0x8f, 0x88, 0xf8, 0x8f, 0xf0, 0xf, + 0xf8, 0x8f, 0x88, 0xf8, 0x8f, 0xf0, 0xf, 0xf8, + 0x8f, 0x88, 0xf8, 0x8f, 0xf0, 0xf, 0xf8, 0x8f, + 0x88, 0xf8, 0x8f, 0xf0, 0xf, 0xf8, 0x8f, 0x88, + 0xf8, 0x8f, 0xf0, 0xf, 0xf9, 0x9f, 0x99, 0xf9, + 0x9f, 0xf0, 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe0, 0x4, 0xef, 0xff, 0xff, 0xff, 0xfe, 0x40, + + /* U+F304 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7e, 0xc2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xff, + 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x8c, 0x1c, + 0xff, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xfc, + 0x1c, 0xff, 0x70, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xfc, 0x1c, 0x80, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xff, 0xfc, 0x10, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x8f, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x7f, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0xe, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x3, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x8f, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0xd, + 0xff, 0xfe, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xdd, 0x83, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+F379 "" */ + 0x0, 0x0, 0x6, 0xad, 0xda, 0x60, 0x0, 0x0, + 0x0, 0x6, 0xff, 0xff, 0xff, 0xff, 0x50, 0x0, + 0x0, 0x8f, 0xff, 0xfe, 0xff, 0xff, 0xf8, 0x0, + 0x5, 0xff, 0xfe, 0xf6, 0xa6, 0xff, 0xff, 0x50, + 0xe, 0xff, 0xf8, 0x0, 0x54, 0xff, 0xff, 0xe0, + 0x5f, 0xff, 0xff, 0x32, 0x60, 0x3f, 0xff, 0xf5, + 0x9f, 0xff, 0xff, 0x6, 0xf9, 0xb, 0xff, 0xf8, + 0xbf, 0xff, 0xfb, 0x1, 0x41, 0x2f, 0xff, 0xfa, + 0xaf, 0xff, 0xf7, 0xe, 0xa1, 0x3f, 0xff, 0xfa, + 0x8f, 0xff, 0x61, 0x2f, 0xf3, 0xe, 0xff, 0xf8, + 0x3f, 0xff, 0xa4, 0x0, 0x0, 0x4f, 0xff, 0xf3, + 0xc, 0xff, 0xf6, 0xa1, 0xbb, 0xff, 0xff, 0xc0, + 0x2, 0xff, 0xfe, 0xe9, 0xff, 0xff, 0xff, 0x20, + 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, + 0x0, 0x2, 0xbf, 0xff, 0xff, 0xfb, 0x20, 0x0, + 0x0, 0x0, 0x2, 0x68, 0x86, 0x20, 0x0, 0x0, + + /* U+F55A "" */ + 0x0, 0x0, 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe4, 0x0, 0x1, 0xdf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x0, 0x1d, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x1, 0xdf, 0xff, 0xff, 0x98, + 0xff, 0x89, 0xff, 0xff, 0x1d, 0xff, 0xff, 0xff, + 0x80, 0x77, 0x8, 0xff, 0xff, 0xcf, 0xff, 0xff, + 0xff, 0xf7, 0x0, 0x7f, 0xff, 0xff, 0xcf, 0xff, + 0xff, 0xff, 0xf7, 0x0, 0x7f, 0xff, 0xff, 0x1d, + 0xff, 0xff, 0xff, 0x80, 0x77, 0x8, 0xff, 0xff, + 0x1, 0xdf, 0xff, 0xff, 0x98, 0xff, 0x89, 0xff, + 0xff, 0x0, 0x1d, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x0, 0x1, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0x0, 0x0, 0x1b, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe4, + + /* U+F7C2 "" */ + 0x0, 0x1b, 0xff, 0xff, 0xff, 0xe4, 0x1, 0xdf, + 0xff, 0xff, 0xff, 0xfe, 0x1d, 0xfa, 0x2f, 0x2d, + 0x73, 0xff, 0xbf, 0xf7, 0xf, 0xb, 0x40, 0xff, + 0xff, 0xfa, 0x2f, 0x2d, 0x73, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x4e, 0xff, 0xff, 0xff, 0xff, 0xe4, + + /* U+F8A2 "" */ + 0x0, 0x1, 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xdf, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0xfd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0x1d, 0xfd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xdf, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xcc, 0x0, 0x0, 0x0, 0x0, 0x0 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 154, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 0, .adv_w = 154, .box_w = 3, .box_h = 11, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 17, .adv_w = 154, .box_w = 6, .box_h = 5, .ofs_x = 2, .ofs_y = 6}, + {.bitmap_index = 32, .adv_w = 154, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 82, .adv_w = 154, .box_w = 8, .box_h = 15, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 142, .adv_w = 154, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 192, .adv_w = 154, .box_w = 8, .box_h = 12, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 240, .adv_w = 154, .box_w = 3, .box_h = 5, .ofs_x = 3, .ofs_y = 6}, + {.bitmap_index = 248, .adv_w = 154, .box_w = 5, .box_h = 15, .ofs_x = 2, .ofs_y = -3}, + {.bitmap_index = 286, .adv_w = 154, .box_w = 6, .box_h = 15, .ofs_x = 2, .ofs_y = -3}, + {.bitmap_index = 331, .adv_w = 154, .box_w = 9, .box_h = 9, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 372, .adv_w = 154, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 404, .adv_w = 154, .box_w = 4, .box_h = 5, .ofs_x = 2, .ofs_y = -2}, + {.bitmap_index = 414, .adv_w = 154, .box_w = 8, .box_h = 3, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 426, .adv_w = 154, .box_w = 3, .box_h = 3, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 431, .adv_w = 154, .box_w = 8, .box_h = 15, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 491, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 531, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 571, .adv_w = 154, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 606, .adv_w = 154, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 641, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 681, .adv_w = 154, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 716, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 756, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 796, .adv_w = 154, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 831, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 871, .adv_w = 154, .box_w = 3, .box_h = 8, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 883, .adv_w = 154, .box_w = 4, .box_h = 10, .ofs_x = 3, .ofs_y = -2}, + {.bitmap_index = 903, .adv_w = 154, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 939, .adv_w = 154, .box_w = 8, .box_h = 6, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 963, .adv_w = 154, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 995, .adv_w = 154, .box_w = 6, .box_h = 12, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1031, .adv_w = 154, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 1086, .adv_w = 154, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1131, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1171, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1211, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1251, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1291, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1331, .adv_w = 154, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1376, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1416, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1456, .adv_w = 154, .box_w = 7, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1491, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1531, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1571, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1611, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1651, .adv_w = 154, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1696, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1736, .adv_w = 154, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 1786, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1826, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1866, .adv_w = 154, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1911, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1951, .adv_w = 154, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 1996, .adv_w = 154, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2046, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2086, .adv_w = 154, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2131, .adv_w = 154, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2171, .adv_w = 154, .box_w = 5, .box_h = 15, .ofs_x = 2, .ofs_y = -4}, + {.bitmap_index = 2209, .adv_w = 154, .box_w = 8, .box_h = 15, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 2269, .adv_w = 154, .box_w = 6, .box_h = 15, .ofs_x = 2, .ofs_y = -4}, + {.bitmap_index = 2314, .adv_w = 154, .box_w = 7, .box_h = 6, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 2335, .adv_w = 154, .box_w = 10, .box_h = 3, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 2350, .adv_w = 154, .box_w = 5, .box_h = 3, .ofs_x = 2, .ofs_y = 9}, + {.bitmap_index = 2358, .adv_w = 154, .box_w = 7, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2386, .adv_w = 154, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2430, .adv_w = 154, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2462, .adv_w = 154, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2506, .adv_w = 154, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2538, .adv_w = 154, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2582, .adv_w = 154, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 2626, .adv_w = 154, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2670, .adv_w = 154, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2714, .adv_w = 154, .box_w = 7, .box_h = 14, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 2763, .adv_w = 154, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2807, .adv_w = 154, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2851, .adv_w = 154, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 2887, .adv_w = 154, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2919, .adv_w = 154, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2951, .adv_w = 154, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 2995, .adv_w = 154, .box_w = 8, .box_h = 11, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 3039, .adv_w = 154, .box_w = 7, .box_h = 8, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 3067, .adv_w = 154, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3099, .adv_w = 154, .box_w = 9, .box_h = 10, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3144, .adv_w = 154, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3176, .adv_w = 154, .box_w = 9, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3212, .adv_w = 154, .box_w = 10, .box_h = 8, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3252, .adv_w = 154, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3284, .adv_w = 154, .box_w = 9, .box_h = 11, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 3334, .adv_w = 154, .box_w = 8, .box_h = 8, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3366, .adv_w = 154, .box_w = 7, .box_h = 15, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 3419, .adv_w = 154, .box_w = 2, .box_h = 15, .ofs_x = 4, .ofs_y = -3}, + {.bitmap_index = 3434, .adv_w = 154, .box_w = 8, .box_h = 15, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 3494, .adv_w = 154, .box_w = 8, .box_h = 4, .ofs_x = 1, .ofs_y = 3}, + {.bitmap_index = 3510, .adv_w = 154, .box_w = 6, .box_h = 6, .ofs_x = 1, .ofs_y = 5}, + {.bitmap_index = 3528, .adv_w = 154, .box_w = 5, .box_h = 5, .ofs_x = 2, .ofs_y = 3}, + {.bitmap_index = 3541, .adv_w = 160, .box_w = 10, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 3621, .adv_w = 256, .box_w = 16, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 3757, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3869, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 3981, .adv_w = 256, .box_w = 14, .box_h = 10, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 4051, .adv_w = 160, .box_w = 10, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 4101, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4229, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4357, .adv_w = 288, .box_w = 19, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4519, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4647, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 4759, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4887, .adv_w = 160, .box_w = 10, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 4967, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 5079, .adv_w = 320, .box_w = 20, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 5239, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 5351, .adv_w = 192, .box_w = 12, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 5453, .adv_w = 160, .box_w = 10, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 5523, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 5619, .adv_w = 160, .box_w = 10, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 5679, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 5751, .adv_w = 160, .box_w = 10, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 5821, .adv_w = 224, .box_w = 16, .box_h = 14, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 5933, .adv_w = 192, .box_w = 8, .box_h = 14, .ofs_x = 1, .ofs_y = -1}, + {.bitmap_index = 5989, .adv_w = 192, .box_w = 8, .box_h = 14, .ofs_x = 3, .ofs_y = -1}, + {.bitmap_index = 6045, .adv_w = 224, .box_w = 14, .box_h = 13, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 6136, .adv_w = 224, .box_w = 14, .box_h = 2, .ofs_x = 0, .ofs_y = 5}, + {.bitmap_index = 6150, .adv_w = 288, .box_w = 20, .box_h = 14, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 6290, .adv_w = 320, .box_w = 22, .box_h = 18, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 6488, .adv_w = 256, .box_w = 18, .box_h = 14, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 6614, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 6742, .adv_w = 256, .box_w = 14, .box_h = 8, .ofs_x = 1, .ofs_y = 3}, + {.bitmap_index = 6798, .adv_w = 256, .box_w = 14, .box_h = 8, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 6854, .adv_w = 288, .box_w = 20, .box_h = 12, .ofs_x = -1, .ofs_y = 0}, + {.bitmap_index = 6974, .adv_w = 256, .box_w = 16, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 7086, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 7214, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 7359, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 7487, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 7615, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 7713, .adv_w = 224, .box_w = 14, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7797, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 7893, .adv_w = 224, .box_w = 14, .box_h = 18, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 8019, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 8147, .adv_w = 224, .box_w = 16, .box_h = 16, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 8275, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 8383, .adv_w = 224, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 8481, .adv_w = 192, .box_w = 12, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 8565, .adv_w = 320, .box_w = 20, .box_h = 14, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 8705, .adv_w = 288, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 8795, .adv_w = 288, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 8885, .adv_w = 288, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 8975, .adv_w = 288, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 9065, .adv_w = 288, .box_w = 18, .box_h = 10, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 9155, .adv_w = 320, .box_w = 21, .box_h = 14, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 9302, .adv_w = 224, .box_w = 12, .box_h = 18, .ofs_x = 1, .ofs_y = -3}, + {.bitmap_index = 9410, .adv_w = 224, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 9522, .adv_w = 256, .box_w = 17, .box_h = 17, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 9667, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 9795, .adv_w = 288, .box_w = 18, .box_h = 12, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 9903, .adv_w = 192, .box_w = 12, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 9999, .adv_w = 256, .box_w = 16, .box_h = 10, .ofs_x = 0, .ofs_y = 1} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_1[] = { + 0x0, 0x1f72, 0xe004, 0xef51, 0xef58, 0xef5b, 0xef5c, 0xef5d, + 0xef61, 0xef63, 0xef65, 0xef69, 0xef6c, 0xef71, 0xef76, 0xef77, + 0xef78, 0xef8e, 0xef93, 0xef98, 0xef9b, 0xef9c, 0xef9d, 0xefa1, + 0xefa2, 0xefa3, 0xefa4, 0xefb7, 0xefb8, 0xefbe, 0xefc0, 0xefc1, + 0xefc4, 0xefc7, 0xefc8, 0xefc9, 0xefcb, 0xefe3, 0xefe5, 0xf014, + 0xf015, 0xf017, 0xf019, 0xf030, 0xf037, 0xf03a, 0xf043, 0xf06c, + 0xf074, 0xf0a8, 0xf13b, 0xf190, 0xf191, 0xf192, 0xf193, 0xf194, + 0xf1d7, 0xf1e3, 0xf23d, 0xf254, 0xf2c9, 0xf4aa, 0xf712, 0xf7f2 +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 95, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 176, .range_length = 63475, .glyph_id_start = 96, + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 64, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + + + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LVGL_VERSION_MAJOR >= 8 +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 2, + .bpp = 4, + .kern_classes = 0, + .bitmap_format = 0, +#if LVGL_VERSION_MAJOR >= 8 + .cache = &cache +#endif +}; + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t lv_font_courierprimecode_16 = { +#else +lv_font_t lv_font_courierprimecode_16 = { +#endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 19, /*The maximum line height required by the font*/ + .base_line = 4, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -1, + .underline_thickness = 1, +#endif + .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +}; + + + +#endif /*#if LV_FONT_COURIERPRIMECODE_16*/ + diff --git a/src/ui/c/lv_font_courierprimecode_24.c b/src/ui/c/lv_font_courierprimecode_24.c new file mode 100644 index 0000000..c7287d4 --- /dev/null +++ b/src/ui/c/lv_font_courierprimecode_24.c @@ -0,0 +1,3347 @@ +/******************************************************************************* + * Size: 24 px + * Bpp: 4 + * Opts: --no-compress --no-prefilter --bpp 4 --size 24 --font courier-prime-code.ttf -r 0x20-0x7F,0xB0,0x2022 --font fa-brands-400.ttf -r 0xF287,0xF293,0xF379 --font fa-solid-900.ttf -r 0xF001,0xF008,0xF00B,0xF00C,0xF00D,0xF011,0xF013,0xF015,0xF019,0xF01C,0xF021,0xF026,0xF027,0xF028,0xF03E,0xF043,0xF048,0xF04B,0xF04C,0xF04D,0xF051,0xF052,0xF053,0xF054,0xF067,0xF068,0xF06E,0xF070,0xF071,0xF074,0xF077,0xF078,0xF079,0xF07B,0xF093,0xF095,0xF0C4,0xF0C5,0xF0C7,0xF0C9,0xF0E0,0xF0E7,0xF0EA,0xF0F3,0xF11C,0xF124,0xF158,0xF1EB,0xF240,0xF241,0xF242,0xF243,0xF244,0xF2ED,0xF304,0xF55A,0xF7C2,0xF177=>0xF8A2,0xE0B4,0xF0E7 --format lvgl -o lv_font_courierprimecode_24.c --force-fast-kern-format + ******************************************************************************/ + +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#ifndef LV_FONT_COURIERPRIMECODE_24 +#define LV_FONT_COURIERPRIMECODE_24 1 +#endif + +#if LV_FONT_COURIERPRIMECODE_24 + +/*----------------- + * BITMAPS + *----------------*/ + +/*Store the image of the glyphs*/ +static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { + /* U+0020 " " */ + + /* U+0021 "!" */ + 0xf, 0xf5, 0xf, 0xf5, 0xe, 0xf4, 0xd, 0xf3, + 0xc, 0xf2, 0xb, 0xf1, 0xa, 0xf0, 0x9, 0xf0, + 0x7, 0xd0, 0x1, 0x30, 0x0, 0x0, 0x2, 0x30, + 0x3f, 0xf9, 0x4f, 0xfa, 0x2e, 0xf8, + + /* U+0022 "\"" */ + 0x57, 0x60, 0x2, 0x76, 0x1d, 0xff, 0x0, 0x7f, + 0xf5, 0xbf, 0xd0, 0x5, 0xff, 0x39, 0xfb, 0x0, + 0x3f, 0xf1, 0x7f, 0x90, 0x1, 0xff, 0x5, 0xf7, + 0x0, 0xf, 0xd0, 0x2e, 0x40, 0x0, 0xb9, 0x0, + + /* U+0023 "#" */ + 0x0, 0x0, 0x2, 0xe3, 0x0, 0x7d, 0x0, 0x0, + 0x0, 0x6, 0xf2, 0x0, 0xcc, 0x0, 0x0, 0x0, + 0xa, 0xe0, 0x1, 0xf8, 0x0, 0x0, 0x0, 0xe, + 0xa0, 0x5, 0xf3, 0x0, 0x5, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf8, 0x3, 0xaa, 0xdf, 0xaa, 0xaf, + 0xea, 0xa5, 0x0, 0x0, 0xbd, 0x0, 0x1f, 0x60, + 0x0, 0x0, 0x0, 0xf8, 0x0, 0x6f, 0x20, 0x0, + 0x1a, 0xab, 0xfc, 0xaa, 0xdf, 0xaa, 0x70, 0x3f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0, 0xd, + 0xb0, 0x3, 0xf5, 0x0, 0x0, 0x0, 0x1f, 0x70, + 0x7, 0xf1, 0x0, 0x0, 0x0, 0x5f, 0x30, 0xb, + 0xd0, 0x0, 0x0, 0x0, 0x6d, 0x0, 0xc, 0x70, + 0x0, 0x0, + + /* U+0024 "$" */ + 0x0, 0x0, 0x35, 0x0, 0x0, 0x0, 0x0, 0xa, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xf0, 0x0, 0x0, 0x3, 0xae, + 0xff, 0xea, 0x50, 0x3, 0xff, 0xdb, 0xce, 0xff, + 0xb0, 0xaf, 0x60, 0x0, 0x2, 0x86, 0xc, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x9f, 0xb4, 0x10, 0x0, + 0x0, 0x1, 0xcf, 0xff, 0xfd, 0xa5, 0x0, 0x0, + 0x36, 0x9b, 0xdf, 0xf9, 0x0, 0x0, 0x0, 0x0, + 0x2d, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x8f, 0x49, + 0xa4, 0x0, 0x0, 0x1d, 0xf2, 0xbf, 0xfe, 0xbb, + 0xcf, 0xf9, 0x0, 0x4a, 0xdf, 0xff, 0xc6, 0x0, + 0x0, 0x0, 0xbf, 0x0, 0x0, 0x0, 0x0, 0xb, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x0, 0x0, + 0x0, 0x0, 0x3, 0x50, 0x0, 0x0, + + /* U+0025 "%" */ + 0x2, 0xbf, 0xe7, 0x0, 0x0, 0x0, 0x0, 0xe, + 0xf9, 0xbf, 0x80, 0x0, 0x1, 0x60, 0x5f, 0x40, + 0xb, 0xe0, 0x0, 0x2e, 0xf1, 0x5f, 0x40, 0xb, + 0xe0, 0x3, 0xef, 0x40, 0xe, 0xe9, 0xbf, 0x80, + 0x4f, 0xe3, 0x0, 0x2, 0xbf, 0xe8, 0x5, 0xfd, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xfc, 0x14, 0x75, 0x0, + 0x0, 0x0, 0x9f, 0xb0, 0xaf, 0xff, 0xc0, 0x0, + 0xa, 0xfa, 0x5, 0xf8, 0x15, 0xf8, 0x0, 0xbf, + 0x80, 0x9, 0xf0, 0x0, 0xcc, 0xa, 0xf7, 0x0, + 0x7, 0xf2, 0x0, 0xeb, 0x3, 0x40, 0x0, 0x1, + 0xfe, 0x9d, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x3c, + 0xfd, 0x50, + + /* U+0026 "&" */ + 0x0, 0x1, 0xae, 0xfd, 0x92, 0x0, 0x0, 0x1e, + 0xfd, 0xce, 0xff, 0x0, 0x0, 0x9f, 0x80, 0x0, + 0x58, 0x0, 0x0, 0xdf, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdf, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x5f, 0xfc, 0x0, 0x5, 0xf4, + 0x4, 0xfe, 0xaf, 0xb0, 0xa, 0xf2, 0xd, 0xf2, + 0xa, 0xfa, 0x1f, 0xc0, 0x1f, 0xb0, 0x0, 0xbf, + 0xdf, 0x60, 0x1f, 0xb0, 0x0, 0xc, 0xfe, 0x0, + 0xd, 0xf4, 0x0, 0x2d, 0xff, 0x60, 0x4, 0xff, + 0xbb, 0xff, 0x8d, 0xf5, 0x0, 0x3b, 0xff, 0xb4, + 0x2, 0xd8, + + /* U+0027 "'" */ + 0x6, 0x73, 0x3f, 0xf9, 0x1f, 0xf7, 0xf, 0xf5, + 0xd, 0xf3, 0xb, 0xf1, 0x7, 0xd0, + + /* U+0028 "(" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xd0, + 0x0, 0x0, 0xcf, 0xc0, 0x0, 0xc, 0xf9, 0x0, + 0x0, 0x8f, 0xa0, 0x0, 0x2, 0xfd, 0x0, 0x0, + 0x9, 0xf4, 0x0, 0x0, 0xe, 0xd0, 0x0, 0x0, + 0x3f, 0x80, 0x0, 0x0, 0x6f, 0x50, 0x0, 0x0, + 0x7f, 0x30, 0x0, 0x0, 0x7f, 0x30, 0x0, 0x0, + 0x6f, 0x50, 0x0, 0x0, 0x3f, 0x80, 0x0, 0x0, + 0xe, 0xc0, 0x0, 0x0, 0x9, 0xf4, 0x0, 0x0, + 0x2, 0xfd, 0x0, 0x0, 0x0, 0x8f, 0xa0, 0x0, + 0x0, 0xc, 0xfa, 0x0, 0x0, 0x0, 0xcf, 0xc0, + 0x0, 0x0, 0x8, 0xd0, + + /* U+0029 ")" */ + 0x7c, 0x20, 0x0, 0x6, 0xff, 0x30, 0x0, 0x5, + 0xff, 0x30, 0x0, 0x5, 0xfd, 0x0, 0x0, 0x8, + 0xf7, 0x0, 0x0, 0xd, 0xe0, 0x0, 0x0, 0x7f, + 0x50, 0x0, 0x2, 0xf9, 0x0, 0x0, 0xf, 0xc0, + 0x0, 0x0, 0xdd, 0x0, 0x0, 0xd, 0xd0, 0x0, + 0x0, 0xec, 0x0, 0x0, 0x1f, 0xa0, 0x0, 0x6, + 0xf5, 0x0, 0x0, 0xdf, 0x10, 0x0, 0x7f, 0x80, + 0x0, 0x4f, 0xd0, 0x0, 0x4f, 0xf3, 0x0, 0x6f, + 0xf4, 0x0, 0x8, 0xd2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+002A "*" */ + 0x0, 0x0, 0x4, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xdf, 0x40, 0x0, 0x0, 0x0, 0x0, 0xc, + 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x10, + 0x0, 0x0, 0x7e, 0x81, 0x9, 0xf0, 0x5, 0xcc, + 0xa, 0xff, 0xfa, 0x9e, 0x7e, 0xff, 0xf1, 0x4, + 0x7a, 0xdf, 0xfe, 0xb8, 0x51, 0x0, 0x0, 0x4, + 0xff, 0x90, 0x0, 0x0, 0x0, 0x3, 0xfb, 0x5f, + 0x80, 0x0, 0x0, 0x2, 0xef, 0x20, 0xcf, 0x70, + 0x0, 0x0, 0xdf, 0x90, 0x3, 0xff, 0x40, 0x0, + 0xa, 0xd1, 0x0, 0x8, 0xe2, 0x0, + + /* U+002B "+" */ + 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x0, 0x9, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x0, 0x0, + 0x0, 0x0, 0xa, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0xaf, 0x0, 0x0, 0xe, 0xff, 0xff, 0xff, 0xff, + 0xf4, 0x8a, 0xaa, 0xef, 0xaa, 0xaa, 0x20, 0x0, + 0xa, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x8e, 0x0, 0x0, 0x0, + + /* U+002C "," */ + 0x5, 0xdd, 0x90, 0xbf, 0xf6, 0xe, 0xff, 0x1, + 0xff, 0x80, 0x4f, 0xf1, 0x7, 0xfa, 0x0, 0x8e, + 0x30, 0x0, + + /* U+002D "-" */ + 0x8a, 0xaa, 0xaa, 0xaa, 0xaa, 0x2d, 0xff, 0xff, + 0xff, 0xff, 0xf4, + + /* U+002E "." */ + 0x18, 0x94, 0x6f, 0xfc, 0x6f, 0xfc, 0x4f, 0xf9, + + /* U+002F "/" */ + 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xe0, 0x0, 0x0, 0x0, 0x6, 0xf8, + 0x0, 0x0, 0x0, 0x0, 0xdf, 0x20, 0x0, 0x0, + 0x0, 0x3f, 0xb0, 0x0, 0x0, 0x0, 0xa, 0xf5, + 0x0, 0x0, 0x0, 0x1, 0xfe, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0x80, 0x0, 0x0, 0x0, 0xd, 0xf1, + 0x0, 0x0, 0x0, 0x4, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0xaf, 0x40, 0x0, 0x0, 0x0, 0x1f, 0xd0, + 0x0, 0x0, 0x0, 0x8, 0xf7, 0x0, 0x0, 0x0, + 0x0, 0xef, 0x10, 0x0, 0x0, 0x0, 0x5f, 0xa0, + 0x0, 0x0, 0x0, 0xb, 0xf3, 0x0, 0x0, 0x0, + 0x2, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x8f, 0x60, + 0x0, 0x0, 0x0, 0xe, 0xf0, 0x0, 0x0, 0x0, + 0x5, 0xf9, 0x0, 0x0, 0x0, 0x0, 0x8e, 0x20, + 0x0, 0x0, 0x0, 0x0, + + /* U+0030 "0" */ + 0x0, 0x19, 0xef, 0xc4, 0x0, 0x0, 0x1e, 0xfd, + 0xcf, 0xf6, 0x0, 0xb, 0xf7, 0x0, 0x2e, 0xf2, + 0x3, 0xfb, 0x0, 0x0, 0xbf, 0x90, 0x7f, 0x50, + 0x0, 0x9f, 0xfe, 0xa, 0xf2, 0x0, 0x7f, 0xac, + 0xf0, 0xbf, 0x10, 0x6f, 0xb0, 0xbf, 0x2b, 0xf1, + 0x5f, 0xc0, 0xa, 0xf2, 0xaf, 0x7f, 0xd1, 0x0, + 0xcf, 0x7, 0xff, 0xe1, 0x0, 0xf, 0xe0, 0x3f, + 0xf2, 0x0, 0x5, 0xf9, 0x0, 0xbf, 0x60, 0x2, + 0xef, 0x20, 0x2, 0xef, 0xdc, 0xff, 0x60, 0x0, + 0x1, 0x9e, 0xfc, 0x40, 0x0, + + /* U+0031 "1" */ + 0x0, 0x0, 0x5d, 0x50, 0x0, 0x0, 0x2, 0xbf, + 0xf6, 0x0, 0x0, 0x8, 0xff, 0xcf, 0x60, 0x0, + 0x5, 0xfd, 0x35, 0xf6, 0x0, 0x0, 0x5, 0x0, + 0x5f, 0x60, 0x0, 0x0, 0x0, 0x5, 0xf6, 0x0, + 0x0, 0x0, 0x0, 0x5f, 0x60, 0x0, 0x0, 0x0, + 0x5, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x5f, 0x60, + 0x0, 0x0, 0x0, 0x5, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0x5f, 0x60, 0x0, 0x0, 0x0, 0x5, 0xf6, + 0x0, 0x0, 0x1a, 0xaa, 0xcf, 0xca, 0xa9, 0x1, + 0xff, 0xff, 0xff, 0xff, 0xf1, + + /* U+0032 "2" */ + 0x1, 0x8d, 0xff, 0xc5, 0x0, 0x4f, 0xff, 0xcc, + 0xff, 0x80, 0x4d, 0x60, 0x0, 0x2e, 0xf1, 0x0, + 0x0, 0x0, 0x8, 0xf5, 0x0, 0x0, 0x0, 0x7, + 0xf5, 0x0, 0x0, 0x0, 0xc, 0xf2, 0x0, 0x0, + 0x0, 0x8f, 0xa0, 0x0, 0x0, 0x6, 0xfd, 0x0, + 0x0, 0x0, 0x6f, 0xd1, 0x0, 0x0, 0x6, 0xfd, + 0x10, 0x0, 0x0, 0x6f, 0xd1, 0x0, 0x0, 0x6, + 0xfd, 0x10, 0x0, 0x0, 0x5f, 0xfc, 0xaa, 0xaa, + 0xa7, 0x8f, 0xff, 0xff, 0xff, 0xfc, + + /* U+0033 "3" */ + 0x3, 0x9d, 0xfe, 0xb4, 0x0, 0x5f, 0xfe, 0xcc, + 0xff, 0x60, 0x2a, 0x40, 0x0, 0x2e, 0xf0, 0x0, + 0x0, 0x0, 0x9, 0xf3, 0x0, 0x0, 0x0, 0xa, + 0xf2, 0x0, 0x0, 0x1, 0x7f, 0xc0, 0x0, 0x8, + 0xff, 0xfd, 0x10, 0x0, 0x3, 0x9a, 0xdf, 0xa0, + 0x0, 0x0, 0x0, 0xa, 0xf6, 0x0, 0x0, 0x0, + 0x3, 0xfa, 0x0, 0x0, 0x0, 0x3, 0xfa, 0x9d, + 0x50, 0x0, 0x1c, 0xf5, 0x8f, 0xfe, 0xcc, 0xff, + 0xb0, 0x2, 0x9d, 0xff, 0xc7, 0x0, + + /* U+0034 "4" */ + 0x0, 0x0, 0x0, 0x4e, 0xa0, 0x0, 0x0, 0x0, + 0x1, 0xef, 0xd0, 0x0, 0x0, 0x0, 0xa, 0xff, + 0xd0, 0x0, 0x0, 0x0, 0x5f, 0x8d, 0xd0, 0x0, + 0x0, 0x1, 0xed, 0xe, 0xd0, 0x0, 0x0, 0xa, + 0xf4, 0xe, 0xd0, 0x0, 0x0, 0x5f, 0x90, 0xe, + 0xd0, 0x0, 0x1, 0xee, 0x10, 0xe, 0xd0, 0x0, + 0xa, 0xf5, 0x0, 0xe, 0xd0, 0x0, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0xf5, 0x1a, 0xaa, 0xaa, 0xaf, + 0xfa, 0xa3, 0x0, 0x0, 0x0, 0xf, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xd0, 0x0, 0x0, 0x0, + 0x0, 0xd, 0xb0, 0x0, + + /* U+0035 "5" */ + 0xa, 0xff, 0xff, 0xff, 0xe0, 0xc, 0xfa, 0xaa, + 0xaa, 0x90, 0xd, 0xd0, 0x0, 0x0, 0x0, 0xe, + 0xd0, 0x0, 0x0, 0x0, 0xe, 0xd5, 0xab, 0x92, + 0x0, 0xf, 0xff, 0xff, 0xff, 0x60, 0xd, 0xc5, + 0x10, 0x5f, 0xf3, 0x0, 0x0, 0x0, 0x6, 0xf9, + 0x0, 0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x0, + 0x0, 0xfc, 0x0, 0x0, 0x0, 0x4, 0xf9, 0x9e, + 0x60, 0x0, 0x2d, 0xf3, 0x7f, 0xfe, 0xcc, 0xff, + 0x80, 0x2, 0x8d, 0xfe, 0xb5, 0x0, + + /* U+0036 "6" */ + 0x0, 0x0, 0x18, 0xce, 0xf4, 0x0, 0x0, 0x7f, + 0xff, 0xdc, 0x30, 0x0, 0x9f, 0xe5, 0x0, 0x0, + 0x0, 0x6f, 0xc0, 0x0, 0x0, 0x0, 0xe, 0xf1, + 0x0, 0x0, 0x0, 0x4, 0xf9, 0x28, 0xb9, 0x50, + 0x0, 0x7f, 0xaf, 0xff, 0xff, 0xb0, 0x9, 0xff, + 0x81, 0x3, 0xbf, 0x80, 0x9f, 0x90, 0x0, 0x0, + 0xef, 0x7, 0xf6, 0x0, 0x0, 0xb, 0xf1, 0x3f, + 0x80, 0x0, 0x0, 0xdf, 0x0, 0xdf, 0x40, 0x0, + 0x7f, 0xb0, 0x3, 0xff, 0xdb, 0xef, 0xe2, 0x0, + 0x2, 0xae, 0xfd, 0x91, 0x0, + + /* U+0037 "7" */ + 0x8f, 0xff, 0xff, 0xff, 0xfe, 0x5, 0xaa, 0xaa, + 0xaa, 0xbf, 0xe0, 0x0, 0x0, 0x0, 0x6, 0xf7, + 0x0, 0x0, 0x0, 0x0, 0xcf, 0x10, 0x0, 0x0, + 0x0, 0x3f, 0xa0, 0x0, 0x0, 0x0, 0x9, 0xf4, + 0x0, 0x0, 0x0, 0x1, 0xfd, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0x60, 0x0, 0x0, 0x0, 0xd, 0xf1, + 0x0, 0x0, 0x0, 0x4, 0xf9, 0x0, 0x0, 0x0, + 0x0, 0xbf, 0x30, 0x0, 0x0, 0x0, 0x1f, 0xc0, + 0x0, 0x0, 0x0, 0x8, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0xad, 0x0, 0x0, 0x0, + + /* U+0038 "8" */ + 0x0, 0x2a, 0xef, 0xc6, 0x0, 0x3, 0xff, 0xdc, + 0xff, 0x90, 0xd, 0xf5, 0x0, 0x1d, 0xf3, 0xf, + 0xb0, 0x0, 0x5, 0xf7, 0xf, 0xd0, 0x0, 0x6, + 0xf6, 0x9, 0xf9, 0x10, 0x5f, 0xe0, 0x0, 0xaf, + 0xff, 0xfe, 0x20, 0x5, 0xff, 0xba, 0xdf, 0xa0, + 0x2f, 0xd1, 0x0, 0x8, 0xf8, 0x7f, 0x50, 0x0, + 0x0, 0xfd, 0x7f, 0x60, 0x0, 0x0, 0xfd, 0x2f, + 0xd2, 0x0, 0x9, 0xf9, 0x8, 0xff, 0xcb, 0xef, + 0xd1, 0x0, 0x4b, 0xef, 0xd8, 0x0, + + /* U+0039 "9" */ + 0x0, 0x5c, 0xff, 0xc5, 0x0, 0x0, 0xaf, 0xfc, + 0xcf, 0xf8, 0x0, 0x4f, 0xc1, 0x0, 0x1c, 0xf3, + 0x9, 0xf3, 0x0, 0x0, 0x2f, 0x90, 0xbf, 0x10, + 0x0, 0x0, 0xfd, 0x8, 0xf5, 0x0, 0x0, 0x3f, + 0xf0, 0x2f, 0xe5, 0x0, 0x4e, 0xff, 0x0, 0x6f, + 0xff, 0xff, 0xbe, 0xd0, 0x0, 0x28, 0xaa, 0x52, + 0xfa, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x40, 0x0, + 0x0, 0x0, 0x7f, 0xc0, 0x0, 0x0, 0x3, 0xaf, + 0xe2, 0x0, 0xa, 0xce, 0xff, 0xc1, 0x0, 0x0, + 0xef, 0xda, 0x40, 0x0, 0x0, + + /* U+003A ":" */ + 0x4e, 0xf9, 0x6f, 0xfc, 0x6f, 0xfc, 0x18, 0x94, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x94, + 0x6f, 0xfc, 0x6f, 0xfc, 0x4f, 0xf9, + + /* U+003B ";" */ + 0x4, 0xef, 0x90, 0x6, 0xff, 0xc0, 0x6, 0xff, + 0xc0, 0x1, 0x89, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xdd, 0xc0, + 0x7, 0xff, 0xa0, 0xa, 0xff, 0x30, 0xd, 0xfc, + 0x0, 0xf, 0xf5, 0x0, 0x3f, 0xe0, 0x0, 0x4f, + 0x60, 0x0, + + /* U+003C "<" */ + 0x0, 0x0, 0x0, 0x0, 0x6, 0xb1, 0x0, 0x0, + 0x0, 0x6, 0xef, 0xf3, 0x0, 0x0, 0x7, 0xef, + 0xe8, 0x10, 0x0, 0x7, 0xef, 0xe7, 0x0, 0x0, + 0x8, 0xef, 0xd6, 0x0, 0x0, 0x0, 0x7f, 0xf8, + 0x0, 0x0, 0x0, 0x0, 0x1b, 0xff, 0xa3, 0x0, + 0x0, 0x0, 0x0, 0x2a, 0xff, 0xb3, 0x0, 0x0, + 0x0, 0x0, 0x2a, 0xff, 0xc4, 0x0, 0x0, 0x0, + 0x0, 0x29, 0xff, 0xc2, 0x0, 0x0, 0x0, 0x0, + 0x19, 0xe2, + + /* U+003D "=" */ + 0xef, 0xff, 0xff, 0xff, 0xff, 0x48, 0xaa, 0xaa, + 0xaa, 0xaa, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8a, 0xaa, + 0xaa, 0xaa, 0xaa, 0x2e, 0xff, 0xff, 0xff, 0xff, + 0xf4, + + /* U+003E ">" */ + 0x89, 0x10, 0x0, 0x0, 0x0, 0xb, 0xff, 0x92, + 0x0, 0x0, 0x0, 0x4, 0xcf, 0xfa, 0x20, 0x0, + 0x0, 0x0, 0x4b, 0xff, 0xa2, 0x0, 0x0, 0x0, + 0x3, 0xbf, 0xfb, 0x20, 0x0, 0x0, 0x0, 0x3e, + 0xfd, 0x0, 0x0, 0x1, 0x7e, 0xfd, 0x50, 0x0, + 0x18, 0xff, 0xd5, 0x0, 0x2, 0x9f, 0xfd, 0x50, + 0x0, 0x9, 0xff, 0xc5, 0x0, 0x0, 0x0, 0xbc, + 0x40, 0x0, 0x0, 0x0, 0x0, + + /* U+003F "?" */ + 0x17, 0xce, 0xfd, 0x70, 0xd, 0xff, 0xdc, 0xff, + 0x90, 0x56, 0x0, 0x1, 0xdf, 0x20, 0x0, 0x0, + 0x8, 0xf4, 0x0, 0x0, 0x0, 0xbf, 0x30, 0x0, + 0x1, 0xaf, 0xd0, 0x0, 0xa, 0xff, 0xc1, 0x0, + 0x2, 0xfe, 0x50, 0x0, 0x0, 0x2f, 0x90, 0x0, + 0x0, 0x1, 0xf8, 0x0, 0x0, 0x0, 0x3, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5c, + 0xa0, 0x0, 0x0, 0xa, 0xff, 0x10, 0x0, 0x0, + 0x7f, 0xe0, 0x0, 0x0, + + /* U+0040 "@" */ + 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4b, 0xff, 0xfd, 0x60, 0x0, 0x0, 0x9, + 0xfd, 0x75, 0x6b, 0xfb, 0x0, 0x0, 0x9f, 0x70, + 0x0, 0x0, 0x4f, 0x90, 0x4, 0xf7, 0x0, 0x1, + 0x0, 0x7, 0xf1, 0xb, 0xd0, 0x3, 0xdf, 0xaa, + 0x40, 0xf7, 0x1f, 0x70, 0x2f, 0xd6, 0xef, 0x50, + 0xc9, 0x4f, 0x20, 0xaf, 0x10, 0xbf, 0x10, 0xbb, + 0x5f, 0x10, 0xf9, 0x0, 0xdc, 0x0, 0xca, 0x5f, + 0x12, 0xf6, 0x3, 0xf9, 0x1, 0xf7, 0x3f, 0x32, + 0xf9, 0x4d, 0xfc, 0x3b, 0xf1, 0xf, 0x80, 0xbf, + 0xfa, 0x5f, 0xff, 0x50, 0x8, 0xf3, 0x4, 0x30, + 0x2, 0x41, 0x0, 0x0, 0xcf, 0x83, 0x22, 0x46, + 0x0, 0x0, 0x0, 0x9, 0xff, 0xff, 0xfe, 0x10, + 0x0, 0x0, 0x0, 0x3, 0x43, 0x20, 0x0, 0x0, + + /* U+0041 "A" */ + 0x0, 0x0, 0x1d, 0xe4, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0xce, + 0x9f, 0x20, 0x0, 0x0, 0x0, 0x2f, 0x93, 0xf8, + 0x0, 0x0, 0x0, 0x9, 0xf3, 0xd, 0xe0, 0x0, + 0x0, 0x0, 0xed, 0x0, 0x8f, 0x40, 0x0, 0x0, + 0x5f, 0x70, 0x2, 0xfa, 0x0, 0x0, 0xb, 0xf2, + 0x0, 0xc, 0xf1, 0x0, 0x1, 0xff, 0xaa, 0xaa, + 0xdf, 0x60, 0x0, 0x7f, 0xff, 0xff, 0xff, 0xfc, + 0x0, 0xd, 0xf1, 0x0, 0x0, 0xb, 0xf2, 0x3, + 0xfa, 0x0, 0x0, 0x0, 0x5f, 0x90, 0x9f, 0x40, + 0x0, 0x0, 0x0, 0xee, 0x9, 0xd0, 0x0, 0x0, + 0x0, 0x8, 0xd1, + + /* U+0042 "B" */ + 0x7f, 0xff, 0xff, 0xea, 0x20, 0x9, 0xfb, 0xaa, + 0xbd, 0xfe, 0x10, 0x9f, 0x20, 0x0, 0x7, 0xf9, + 0x9, 0xf2, 0x0, 0x0, 0xf, 0xc0, 0x9f, 0x20, + 0x0, 0x1, 0xfb, 0x9, 0xf2, 0x0, 0x3, 0xcf, + 0x50, 0x9f, 0xff, 0xff, 0xff, 0xa0, 0x9, 0xfb, + 0xaa, 0xac, 0xff, 0x90, 0x9f, 0x20, 0x0, 0x1, + 0xcf, 0x49, 0xf2, 0x0, 0x0, 0x5, 0xf8, 0x9f, + 0x20, 0x0, 0x0, 0x5f, 0x89, 0xf2, 0x0, 0x0, + 0x1c, 0xf5, 0x9f, 0xba, 0xaa, 0xbf, 0xfc, 0x7, + 0xff, 0xff, 0xff, 0xd7, 0x0, + + /* U+0043 "C" */ + 0x0, 0x1, 0x8d, 0xff, 0xd8, 0x20, 0x0, 0x3e, + 0xfe, 0xcc, 0xff, 0xf6, 0x0, 0xef, 0x70, 0x0, + 0x4, 0xb4, 0x8, 0xf8, 0x0, 0x0, 0x0, 0x0, + 0xd, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0x3f, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x3f, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x1f, 0xb0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xf7, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xef, 0x70, 0x0, 0x4, 0xb4, + 0x0, 0x3e, 0xfe, 0xcc, 0xff, 0xf6, 0x0, 0x1, + 0x8d, 0xff, 0xd8, 0x20, + + /* U+0044 "D" */ + 0xdf, 0xff, 0xfe, 0xb5, 0x0, 0xf, 0xfa, 0xaa, + 0xcf, 0xfa, 0x0, 0xfd, 0x0, 0x0, 0x1b, 0xf9, + 0xf, 0xd0, 0x0, 0x0, 0xd, 0xf2, 0xfd, 0x0, + 0x0, 0x0, 0x5f, 0x8f, 0xd0, 0x0, 0x0, 0x0, + 0xfb, 0xfd, 0x0, 0x0, 0x0, 0xf, 0xdf, 0xd0, + 0x0, 0x0, 0x0, 0xfd, 0xfd, 0x0, 0x0, 0x0, + 0xf, 0xbf, 0xd0, 0x0, 0x0, 0x5, 0xf8, 0xfd, + 0x0, 0x0, 0x0, 0xcf, 0x3f, 0xd0, 0x0, 0x1, + 0xbf, 0x90, 0xff, 0xaa, 0xac, 0xff, 0xb0, 0xd, + 0xff, 0xff, 0xeb, 0x50, 0x0, + + /* U+0045 "E" */ + 0x4f, 0xff, 0xff, 0xff, 0xfd, 0x5, 0xfc, 0xaa, + 0xaa, 0xaa, 0x80, 0x5f, 0x60, 0x0, 0x0, 0x0, + 0x5, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x5f, 0x60, + 0x0, 0x0, 0x0, 0x5, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0x5f, 0xff, 0xff, 0xff, 0x50, 0x5, 0xfc, + 0xaa, 0xaa, 0xa3, 0x0, 0x5f, 0x60, 0x0, 0x0, + 0x0, 0x5, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x5f, + 0x60, 0x0, 0x0, 0x0, 0x5, 0xf6, 0x0, 0x0, + 0x0, 0x0, 0x5f, 0xca, 0xaa, 0xaa, 0xa9, 0x4, + 0xff, 0xff, 0xff, 0xff, 0xf1, + + /* U+0046 "F" */ + 0x1e, 0xff, 0xff, 0xff, 0xff, 0x12, 0xfe, 0xaa, + 0xaa, 0xaa, 0x90, 0x2f, 0xa0, 0x0, 0x0, 0x0, + 0x2, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xa0, + 0x0, 0x0, 0x0, 0x2, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0xea, 0xaa, 0xaa, 0x70, 0x2, 0xff, + 0xff, 0xff, 0xfb, 0x0, 0x2f, 0xa0, 0x0, 0x0, + 0x0, 0x2, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x2f, + 0xa0, 0x0, 0x0, 0x0, 0x2, 0xfa, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0xf8, 0x0, 0x0, 0x0, 0x0, + + /* U+0047 "G" */ + 0x0, 0x3, 0xad, 0xfe, 0xc8, 0x20, 0x0, 0x7f, + 0xfe, 0xcd, 0xff, 0xf3, 0x5, 0xfe, 0x40, 0x0, + 0x5, 0xa1, 0xe, 0xf2, 0x0, 0x0, 0x0, 0x0, + 0x5f, 0x90, 0x0, 0x0, 0x0, 0x0, 0x8f, 0x40, + 0x0, 0x0, 0x0, 0x0, 0xaf, 0x20, 0x0, 0x0, + 0x0, 0x0, 0xaf, 0x20, 0x0, 0xcf, 0xff, 0xf9, + 0x8f, 0x40, 0x0, 0x8a, 0xab, 0xfb, 0x5f, 0x80, + 0x0, 0x0, 0x1, 0xfb, 0xf, 0xf1, 0x0, 0x0, + 0x1, 0xfb, 0x6, 0xfd, 0x30, 0x0, 0x4, 0xfb, + 0x0, 0x8f, 0xfd, 0xbc, 0xef, 0xf8, 0x0, 0x4, + 0xae, 0xff, 0xd9, 0x40, + + /* U+0048 "H" */ + 0xda, 0x0, 0x0, 0x0, 0x4f, 0x3f, 0xd0, 0x0, + 0x0, 0x6, 0xf5, 0xfd, 0x0, 0x0, 0x0, 0x6f, + 0x5f, 0xd0, 0x0, 0x0, 0x6, 0xf5, 0xfd, 0x0, + 0x0, 0x0, 0x6f, 0x5f, 0xd0, 0x0, 0x0, 0x6, + 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5f, 0xfa, + 0xaa, 0xaa, 0xac, 0xf5, 0xfd, 0x0, 0x0, 0x0, + 0x6f, 0x5f, 0xd0, 0x0, 0x0, 0x6, 0xf5, 0xfd, + 0x0, 0x0, 0x0, 0x6f, 0x5f, 0xd0, 0x0, 0x0, + 0x6, 0xf5, 0xfd, 0x0, 0x0, 0x0, 0x6f, 0x5d, + 0xa0, 0x0, 0x0, 0x4, 0xf3, + + /* U+0049 "I" */ + 0x4f, 0xff, 0xff, 0xff, 0xfa, 0x2, 0xaa, 0xae, + 0xfb, 0xaa, 0x60, 0x0, 0x0, 0xbf, 0x10, 0x0, + 0x0, 0x0, 0xb, 0xf1, 0x0, 0x0, 0x0, 0x0, + 0xbf, 0x10, 0x0, 0x0, 0x0, 0xb, 0xf1, 0x0, + 0x0, 0x0, 0x0, 0xbf, 0x10, 0x0, 0x0, 0x0, + 0xb, 0xf1, 0x0, 0x0, 0x0, 0x0, 0xbf, 0x10, + 0x0, 0x0, 0x0, 0xb, 0xf1, 0x0, 0x0, 0x0, + 0x0, 0xbf, 0x10, 0x0, 0x0, 0x0, 0xb, 0xf1, + 0x0, 0x0, 0x5a, 0xaa, 0xef, 0xba, 0xa9, 0x8, + 0xff, 0xff, 0xff, 0xff, 0xe0, + + /* U+004A "J" */ + 0x0, 0x6f, 0xff, 0xff, 0xf1, 0x0, 0x4a, 0xaa, + 0xad, 0xf3, 0x0, 0x0, 0x0, 0x9, 0xf3, 0x0, + 0x0, 0x0, 0x9, 0xf3, 0x0, 0x0, 0x0, 0x9, + 0xf3, 0x0, 0x0, 0x0, 0x9, 0xf3, 0x0, 0x0, + 0x0, 0x9, 0xf3, 0x0, 0x0, 0x0, 0x9, 0xf3, + 0x0, 0x0, 0x0, 0x9, 0xf3, 0x0, 0x0, 0x0, + 0x9, 0xf2, 0x0, 0x0, 0x0, 0xb, 0xf2, 0x9c, + 0x30, 0x0, 0x4f, 0xe0, 0x9f, 0xfe, 0xbd, 0xff, + 0x60, 0x3, 0xad, 0xff, 0xc4, 0x0, + + /* U+004B "K" */ + 0x5f, 0x20, 0x0, 0x0, 0x5e, 0x57, 0xf4, 0x0, + 0x0, 0x5f, 0xe2, 0x7f, 0x40, 0x0, 0x4f, 0xf3, + 0x7, 0xf4, 0x0, 0x4f, 0xf3, 0x0, 0x7f, 0x40, + 0x4f, 0xf3, 0x0, 0x7, 0xf4, 0x3f, 0xf3, 0x0, + 0x0, 0x7f, 0x8f, 0xfc, 0x0, 0x0, 0x7, 0xff, + 0xfc, 0xf9, 0x0, 0x0, 0x7f, 0xf5, 0xd, 0xf5, + 0x0, 0x7, 0xf6, 0x0, 0x2f, 0xf2, 0x0, 0x7f, + 0x40, 0x0, 0x5f, 0xd0, 0x7, 0xf4, 0x0, 0x0, + 0x8f, 0xa0, 0x7f, 0x40, 0x0, 0x0, 0xcf, 0x75, + 0xf2, 0x0, 0x0, 0x1, 0xd8, + + /* U+004C "L" */ + 0xf, 0x80, 0x0, 0x0, 0x0, 0x2, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, 0x0, + 0x2, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xa0, + 0x0, 0x0, 0x0, 0x2, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0xa0, 0x0, 0x0, 0x0, 0x2, 0xfa, + 0x0, 0x0, 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, + 0x0, 0x2, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x2f, + 0xa0, 0x0, 0x0, 0x0, 0x2, 0xfa, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0xea, 0xaa, 0xaa, 0xa9, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xf1, + + /* U+004D "M" */ + 0xc, 0xc0, 0x0, 0x0, 0x7, 0xe3, 0xf, 0xf7, + 0x0, 0x0, 0x1f, 0xf5, 0xf, 0xfe, 0x0, 0x0, + 0x8f, 0xf6, 0xf, 0xff, 0x60, 0x0, 0xef, 0xf6, + 0xf, 0xbe, 0xd0, 0x7, 0xfa, 0xf7, 0x1f, 0xa8, + 0xf5, 0xe, 0xe4, 0xf7, 0x1f, 0x91, 0xfc, 0x6f, + 0x73, 0xf7, 0x2f, 0x90, 0x9f, 0xee, 0x3, 0xf8, + 0x2f, 0x90, 0x1f, 0xf8, 0x2, 0xf8, 0x3f, 0x80, + 0x6, 0xa0, 0x2, 0xf9, 0x3f, 0x80, 0x0, 0x0, + 0x1, 0xf9, 0x4f, 0x70, 0x0, 0x0, 0x1, 0xfa, + 0x4f, 0x70, 0x0, 0x0, 0x1, 0xfa, 0x3f, 0x50, + 0x0, 0x0, 0x0, 0xe9, + + /* U+004E "N" */ + 0xde, 0x20, 0x0, 0x0, 0x4f, 0x3f, 0xfb, 0x0, + 0x0, 0x6, 0xf5, 0xff, 0xf6, 0x0, 0x0, 0x6f, + 0x5f, 0xde, 0xe1, 0x0, 0x6, 0xf5, 0xfc, 0x5f, + 0xb0, 0x0, 0x6f, 0x5f, 0xc0, 0xaf, 0x50, 0x6, + 0xf5, 0xfc, 0x1, 0xee, 0x10, 0x6f, 0x5f, 0xc0, + 0x5, 0xfa, 0x6, 0xf5, 0xfc, 0x0, 0xb, 0xf4, + 0x6f, 0x5f, 0xc0, 0x0, 0x1f, 0xe6, 0xf5, 0xfc, + 0x0, 0x0, 0x6f, 0xef, 0x5f, 0xc0, 0x0, 0x0, + 0xbf, 0xf5, 0xfc, 0x0, 0x0, 0x2, 0xff, 0x5d, + 0xa0, 0x0, 0x0, 0x6, 0xe3, + + /* U+004F "O" */ + 0x0, 0x5, 0xbe, 0xfd, 0x81, 0x0, 0x0, 0xb, + 0xff, 0xdc, 0xef, 0xe3, 0x0, 0xa, 0xfb, 0x10, + 0x0, 0x6f, 0xe1, 0x3, 0xfc, 0x0, 0x0, 0x0, + 0x6f, 0x90, 0x9f, 0x40, 0x0, 0x0, 0x0, 0xef, + 0xc, 0xf0, 0x0, 0x0, 0x0, 0xa, 0xf3, 0xee, + 0x0, 0x0, 0x0, 0x0, 0x8f, 0x4e, 0xe0, 0x0, + 0x0, 0x0, 0x8, 0xf4, 0xcf, 0x0, 0x0, 0x0, + 0x0, 0xaf, 0x39, 0xf4, 0x0, 0x0, 0x0, 0xe, + 0xf0, 0x3f, 0xc0, 0x0, 0x0, 0x6, 0xf9, 0x0, + 0xaf, 0xb1, 0x0, 0x6, 0xff, 0x10, 0x0, 0xbf, + 0xfc, 0xce, 0xfe, 0x30, 0x0, 0x0, 0x5c, 0xef, + 0xd8, 0x10, 0x0, + + /* U+0050 "P" */ + 0x2f, 0xff, 0xff, 0xea, 0x30, 0x4, 0xfd, 0xaa, + 0xbd, 0xff, 0x60, 0x4f, 0x80, 0x0, 0x3, 0xff, + 0x14, 0xf8, 0x0, 0x0, 0x7, 0xf6, 0x4f, 0x80, + 0x0, 0x0, 0x4f, 0x84, 0xf8, 0x0, 0x0, 0x7, + 0xf7, 0x4f, 0x80, 0x0, 0x3, 0xef, 0x24, 0xfd, + 0xaa, 0xbd, 0xff, 0x70, 0x4f, 0xff, 0xff, 0xeb, + 0x40, 0x4, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x4f, + 0x80, 0x0, 0x0, 0x0, 0x4, 0xf8, 0x0, 0x0, + 0x0, 0x0, 0x4f, 0x80, 0x0, 0x0, 0x0, 0x2, + 0xf6, 0x0, 0x0, 0x0, 0x0, + + /* U+0051 "Q" */ + 0x0, 0x5, 0xbe, 0xfd, 0x81, 0x0, 0x0, 0xb, + 0xff, 0xdc, 0xef, 0xe3, 0x0, 0xa, 0xfb, 0x10, + 0x0, 0x6f, 0xe1, 0x3, 0xfc, 0x0, 0x0, 0x0, + 0x6f, 0x90, 0x9f, 0x40, 0x0, 0x0, 0x0, 0xef, + 0xc, 0xf0, 0x0, 0x0, 0x0, 0xa, 0xf3, 0xee, + 0x0, 0x0, 0x0, 0x0, 0x8f, 0x4e, 0xe0, 0x0, + 0x0, 0x0, 0x8, 0xf4, 0xcf, 0x0, 0x0, 0x0, + 0x0, 0xaf, 0x39, 0xf4, 0x0, 0xc, 0x80, 0xe, + 0xf0, 0x3f, 0xc0, 0x0, 0xdf, 0x36, 0xf9, 0x0, + 0xaf, 0xb1, 0x3, 0xfe, 0xff, 0x10, 0x0, 0xbf, + 0xfc, 0xcf, 0xff, 0x30, 0x0, 0x0, 0x5c, 0xef, + 0xde, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x43, 0x0, + + /* U+0052 "R" */ + 0x2f, 0xff, 0xff, 0xe9, 0x20, 0x4, 0xfd, 0xaa, + 0xbd, 0xff, 0x30, 0x4f, 0x80, 0x0, 0x6, 0xfc, + 0x4, 0xf8, 0x0, 0x0, 0xc, 0xf0, 0x4f, 0x80, + 0x0, 0x0, 0xcf, 0x4, 0xf8, 0x0, 0x0, 0x5f, + 0xc0, 0x4f, 0xda, 0xab, 0xdf, 0xf3, 0x4, 0xff, + 0xff, 0xff, 0xa2, 0x0, 0x4f, 0x80, 0x9, 0xf7, + 0x0, 0x4, 0xf8, 0x0, 0xe, 0xf2, 0x0, 0x4f, + 0x80, 0x0, 0x5f, 0xb0, 0x4, 0xf8, 0x0, 0x0, + 0xbf, 0x50, 0x4f, 0x80, 0x0, 0x2, 0xfe, 0x2, + 0xf6, 0x0, 0x0, 0x7, 0xd2, + + /* U+0053 "S" */ + 0x0, 0x19, 0xdf, 0xfd, 0xa5, 0x0, 0x2, 0xef, + 0xec, 0xce, 0xff, 0xd0, 0xb, 0xf8, 0x0, 0x0, + 0x29, 0xa0, 0xe, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0xe, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xfd, + 0x73, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, 0xfd, + 0x93, 0x0, 0x0, 0x0, 0x47, 0xae, 0xff, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x4e, 0xf2, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xf6, 0xd, 0xc5, 0x0, 0x0, 0x3e, 0xf2, + 0xb, 0xff, 0xfc, 0xbd, 0xff, 0x80, 0x0, 0x39, + 0xdf, 0xfe, 0xb4, 0x0, + + /* U+0054 "T" */ + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x4a, 0xaa, + 0xae, 0xfb, 0xaa, 0xa8, 0x0, 0x0, 0xb, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0xb, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xf1, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xf1, 0x0, 0x0, 0x0, 0x0, 0xb, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0xb, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xf1, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xf1, 0x0, 0x0, 0x0, 0x0, 0xb, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0xb, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xf1, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xe0, 0x0, 0x0, + + /* U+0055 "U" */ + 0xda, 0x0, 0x0, 0x0, 0x4f, 0x3f, 0xd0, 0x0, + 0x0, 0x6, 0xf5, 0xfd, 0x0, 0x0, 0x0, 0x6f, + 0x5f, 0xd0, 0x0, 0x0, 0x6, 0xf5, 0xfd, 0x0, + 0x0, 0x0, 0x6f, 0x5f, 0xd0, 0x0, 0x0, 0x6, + 0xf5, 0xfd, 0x0, 0x0, 0x0, 0x6f, 0x5f, 0xd0, + 0x0, 0x0, 0x6, 0xf5, 0xfd, 0x0, 0x0, 0x0, + 0x6f, 0x5e, 0xe0, 0x0, 0x0, 0x8, 0xf4, 0xcf, + 0x20, 0x0, 0x0, 0xcf, 0x26, 0xfc, 0x20, 0x0, + 0x8f, 0xc0, 0xa, 0xff, 0xdc, 0xef, 0xe2, 0x0, + 0x6, 0xce, 0xfd, 0x91, 0x0, + + /* U+0056 "V" */ + 0x9d, 0x0, 0x0, 0x0, 0x0, 0x8d, 0x19, 0xf4, + 0x0, 0x0, 0x0, 0xe, 0xe0, 0x3f, 0xa0, 0x0, + 0x0, 0x5, 0xf8, 0x0, 0xdf, 0x10, 0x0, 0x0, + 0xbf, 0x20, 0x7, 0xf7, 0x0, 0x0, 0x1f, 0xc0, + 0x0, 0x1f, 0xd0, 0x0, 0x7, 0xf6, 0x0, 0x0, + 0xaf, 0x30, 0x0, 0xdf, 0x0, 0x0, 0x4, 0xf9, + 0x0, 0x3f, 0xa0, 0x0, 0x0, 0xe, 0xe0, 0xa, + 0xf4, 0x0, 0x0, 0x0, 0x8f, 0x50, 0xfd, 0x0, + 0x0, 0x0, 0x2, 0xfb, 0x6f, 0x70, 0x0, 0x0, + 0x0, 0xc, 0xfd, 0xf1, 0x0, 0x0, 0x0, 0x0, + 0x6f, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, 0xce, + 0x30, 0x0, 0x0, + + /* U+0057 "W" */ + 0x2f, 0x60, 0x0, 0x0, 0x0, 0x2, 0xf6, 0x1f, + 0xa0, 0x0, 0x0, 0x0, 0x5, 0xf6, 0xf, 0xc0, + 0x0, 0x0, 0x0, 0x7, 0xf4, 0xd, 0xe0, 0x0, + 0xae, 0x0, 0xa, 0xf1, 0xa, 0xf0, 0x1, 0xff, + 0x50, 0xc, 0xf0, 0x8, 0xf2, 0x6, 0xff, 0xb0, + 0xe, 0xd0, 0x6, 0xf5, 0xb, 0xfc, 0xf1, 0xf, + 0xb0, 0x4, 0xf7, 0x1f, 0xa5, 0xf6, 0x2f, 0x80, + 0x1, 0xf9, 0x6f, 0x50, 0xfb, 0x4f, 0x60, 0x0, + 0xfb, 0xcf, 0x0, 0xbf, 0x7f, 0x40, 0x0, 0xde, + 0xfa, 0x0, 0x5f, 0xef, 0x20, 0x0, 0xbf, 0xf4, + 0x0, 0xf, 0xff, 0x0, 0x0, 0x8f, 0xf0, 0x0, + 0xa, 0xfd, 0x0, 0x0, 0x4f, 0x70, 0x0, 0x3, + 0xe9, 0x0, + + /* U+0058 "X" */ + 0xb, 0xd0, 0x0, 0x0, 0x5, 0xe4, 0x9, 0xf9, + 0x0, 0x0, 0x1e, 0xf2, 0x0, 0xdf, 0x40, 0x0, + 0xbf, 0x70, 0x0, 0x3f, 0xe0, 0x6, 0xfb, 0x0, + 0x0, 0x8, 0xf9, 0x1f, 0xe1, 0x0, 0x0, 0x0, + 0xcf, 0xdf, 0x50, 0x0, 0x0, 0x0, 0x2f, 0xfa, + 0x0, 0x0, 0x0, 0x0, 0x4f, 0xfc, 0x0, 0x0, + 0x0, 0x1, 0xef, 0xaf, 0x80, 0x0, 0x0, 0xb, + 0xf5, 0xd, 0xf4, 0x0, 0x0, 0x7f, 0xa0, 0x3, + 0xfe, 0x10, 0x2, 0xfe, 0x10, 0x0, 0x7f, 0xa0, + 0xd, 0xf5, 0x0, 0x0, 0xc, 0xf6, 0x1d, 0x90, + 0x0, 0x0, 0x2, 0xe8, + + /* U+0059 "Y" */ + 0x5e, 0x40, 0x0, 0x0, 0x0, 0xda, 0x2f, 0xe1, + 0x0, 0x0, 0x9, 0xf8, 0x8, 0xfa, 0x0, 0x0, + 0x3f, 0xd0, 0x0, 0xdf, 0x40, 0x0, 0xdf, 0x30, + 0x0, 0x3f, 0xe0, 0x8, 0xf9, 0x0, 0x0, 0x8, + 0xf9, 0x3f, 0xd0, 0x0, 0x0, 0x0, 0xdf, 0xef, + 0x30, 0x0, 0x0, 0x0, 0x3f, 0xf9, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xf1, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xf1, 0x0, 0x0, 0x0, 0x0, 0xb, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0xb, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xf1, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xe0, 0x0, 0x0, + + /* U+005A "Z" */ + 0x9, 0xff, 0xff, 0xff, 0xff, 0xf2, 0x6, 0xaa, + 0xaa, 0xaa, 0xdf, 0xd0, 0x0, 0x0, 0x0, 0x0, + 0xdf, 0x30, 0x0, 0x0, 0x0, 0x9, 0xf8, 0x0, + 0x0, 0x0, 0x0, 0x4f, 0xd0, 0x0, 0x0, 0x0, + 0x1, 0xef, 0x30, 0x0, 0x0, 0x0, 0xa, 0xf8, + 0x0, 0x0, 0x0, 0x0, 0x5f, 0xc0, 0x0, 0x0, + 0x0, 0x1, 0xef, 0x20, 0x0, 0x0, 0x0, 0xb, + 0xf7, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xc0, 0x0, + 0x0, 0x0, 0x1, 0xff, 0x20, 0x0, 0x0, 0x0, + 0xb, 0xfe, 0xaa, 0xaa, 0xaa, 0xa2, 0xe, 0xff, + 0xff, 0xff, 0xff, 0xf4, + + /* U+005B "[" */ + 0x9, 0xaa, 0xaa, 0x91, 0x1f, 0xff, 0xff, 0xf1, + 0x2f, 0xa0, 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, + 0x2f, 0xa0, 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, + 0x2f, 0xa0, 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, + 0x2f, 0xa0, 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, + 0x2f, 0xa0, 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, + 0x2f, 0xa0, 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, + 0x2f, 0xa0, 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, + 0x2f, 0xa0, 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, + 0x2f, 0xea, 0xaa, 0x91, 0xf, 0xff, 0xff, 0xf1, + + /* U+005C "\\" */ + 0x26, 0x0, 0x0, 0x0, 0x0, 0x8, 0xf6, 0x0, + 0x0, 0x0, 0x0, 0x2f, 0xc0, 0x0, 0x0, 0x0, + 0x0, 0xbf, 0x30, 0x0, 0x0, 0x0, 0x5, 0xf9, + 0x0, 0x0, 0x0, 0x0, 0xe, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0x8f, 0x60, 0x0, 0x0, 0x0, 0x1, + 0xfd, 0x0, 0x0, 0x0, 0x0, 0xb, 0xf4, 0x0, + 0x0, 0x0, 0x0, 0x4f, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0xef, 0x10, 0x0, 0x0, 0x0, 0x7, 0xf7, + 0x0, 0x0, 0x0, 0x0, 0x1f, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0xaf, 0x40, 0x0, 0x0, 0x0, 0x4, + 0xfb, 0x0, 0x0, 0x0, 0x0, 0xd, 0xf2, 0x0, + 0x0, 0x0, 0x0, 0x6f, 0x80, 0x0, 0x0, 0x0, + 0x1, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x9, 0xf5, + 0x0, 0x0, 0x0, 0x0, 0x3f, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0xbd, 0x0, + + /* U+005D "]" */ + 0x6a, 0xaa, 0xaa, 0x3a, 0xff, 0xff, 0xf8, 0x0, + 0x0, 0x3f, 0x80, 0x0, 0x3, 0xf8, 0x0, 0x0, + 0x3f, 0x80, 0x0, 0x3, 0xf8, 0x0, 0x0, 0x3f, + 0x80, 0x0, 0x3, 0xf8, 0x0, 0x0, 0x3f, 0x80, + 0x0, 0x3, 0xf8, 0x0, 0x0, 0x3f, 0x80, 0x0, + 0x3, 0xf8, 0x0, 0x0, 0x3f, 0x80, 0x0, 0x3, + 0xf8, 0x0, 0x0, 0x3f, 0x80, 0x0, 0x3, 0xf8, + 0x0, 0x0, 0x3f, 0x80, 0x0, 0x3, 0xf8, 0x6a, + 0xaa, 0xbf, 0x8a, 0xff, 0xff, 0xf6, + + /* U+005E "^" */ + 0x0, 0x0, 0x9e, 0x10, 0x0, 0x0, 0x3, 0xff, + 0x90, 0x0, 0x0, 0xb, 0xfc, 0xf2, 0x0, 0x0, + 0x4f, 0x92, 0xfa, 0x0, 0x0, 0xcf, 0x10, 0xaf, + 0x30, 0x5, 0xf8, 0x0, 0x2f, 0xb0, 0xd, 0xf1, + 0x0, 0xa, 0xf4, 0x2e, 0x70, 0x0, 0x2, 0xe7, + + /* U+005F "_" */ + 0x9, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa4, 0x1f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, + + /* U+0060 "`" */ + 0x5, 0x20, 0x0, 0x3, 0xff, 0x60, 0x0, 0x9, + 0xff, 0xa0, 0x0, 0x3, 0xcf, 0xd2, 0x0, 0x0, + 0x6e, 0x40, + + /* U+0061 "a" */ + 0x0, 0x27, 0xce, 0xfe, 0xb3, 0x0, 0x3f, 0xff, + 0xcb, 0xdf, 0xf3, 0x0, 0x84, 0x0, 0x0, 0x4f, + 0xb0, 0x0, 0x0, 0x0, 0x0, 0xed, 0x0, 0x4a, + 0xef, 0xec, 0x9e, 0xe0, 0x7f, 0xfc, 0xab, 0xdf, + 0xfe, 0xf, 0xf2, 0x0, 0x0, 0xe, 0xe1, 0xfb, + 0x0, 0x0, 0x1, 0xee, 0xf, 0xe0, 0x0, 0x3, + 0xdf, 0xe0, 0x8f, 0xd8, 0x8c, 0xfe, 0xee, 0x0, + 0x6d, 0xff, 0xc7, 0xa, 0xc0, + + /* U+0062 "b" */ + 0xae, 0x0, 0x0, 0x0, 0x0, 0xc, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0xcf, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0x5, + 0xcf, 0xea, 0x30, 0xc, 0xf9, 0xfe, 0xcd, 0xff, + 0x50, 0xcf, 0xf6, 0x0, 0x5, 0xfe, 0x1c, 0xf8, + 0x0, 0x0, 0x8, 0xf7, 0xcf, 0x20, 0x0, 0x0, + 0x2f, 0xac, 0xf0, 0x0, 0x0, 0x1, 0xfb, 0xcf, + 0x20, 0x0, 0x0, 0x2f, 0xac, 0xf7, 0x0, 0x0, + 0x8, 0xf7, 0xcf, 0xf5, 0x0, 0x4, 0xff, 0x1c, + 0xea, 0xfe, 0xbd, 0xff, 0x50, 0xac, 0x6, 0xdf, + 0xea, 0x30, 0x0, + + /* U+0063 "c" */ + 0x0, 0x4, 0xbe, 0xfe, 0xb6, 0x0, 0x0, 0x9f, + 0xfd, 0xcd, 0xff, 0xe2, 0x6, 0xfd, 0x30, 0x0, + 0x17, 0xd2, 0xe, 0xf2, 0x0, 0x0, 0x0, 0x0, + 0x2f, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x2f, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0xe, 0xf2, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xfd, 0x30, 0x0, 0x17, 0xf6, 0x0, 0x9f, + 0xfd, 0xbd, 0xff, 0xe3, 0x0, 0x4, 0xbe, 0xfe, + 0xb6, 0x0, + + /* U+0064 "d" */ + 0x0, 0x0, 0x0, 0x0, 0x7, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0x9, 0xf2, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x9, 0xf2, + 0x0, 0x8, 0xdf, 0xe9, 0x19, 0xf2, 0x1, 0xdf, + 0xfc, 0xdf, 0xdb, 0xf2, 0xa, 0xfa, 0x0, 0x2, + 0xdf, 0xf2, 0x1f, 0xe0, 0x0, 0x0, 0x2f, 0xf2, + 0x4f, 0x90, 0x0, 0x0, 0xc, 0xf2, 0x5f, 0x70, + 0x0, 0x0, 0xa, 0xf2, 0x4f, 0x80, 0x0, 0x0, + 0xb, 0xf2, 0x1f, 0xd0, 0x0, 0x0, 0x1f, 0xf2, + 0xa, 0xf8, 0x0, 0x0, 0xbf, 0xf2, 0x1, 0xdf, + 0xd9, 0xaf, 0xfb, 0xf2, 0x0, 0x8, 0xdf, 0xe9, + 0x26, 0xf1, + + /* U+0065 "e" */ + 0x0, 0x4, 0xbe, 0xfd, 0x92, 0x0, 0x0, 0x9f, + 0xfc, 0xbd, 0xff, 0x50, 0x7, 0xfa, 0x10, 0x0, + 0x3e, 0xf1, 0xe, 0xd0, 0x0, 0x0, 0x5, 0xf7, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x3f, 0xda, + 0xaa, 0xaa, 0xaa, 0xa5, 0x2f, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0xe1, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xfb, 0x10, 0x0, 0x5, 0xb2, 0x0, 0xcf, + 0xfc, 0xbc, 0xff, 0xf4, 0x0, 0x7, 0xcf, 0xfe, + 0xb7, 0x20, + + /* U+0066 "f" */ + 0x0, 0x0, 0x2a, 0xef, 0xeb, 0x50, 0x0, 0x2, + 0xff, 0xdb, 0xcf, 0xf0, 0x0, 0x9, 0xf7, 0x0, + 0x0, 0x20, 0x0, 0xb, 0xf1, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xf0, 0x0, 0x0, 0x0, 0xaf, 0xff, + 0xff, 0xff, 0xfa, 0x0, 0x6a, 0xae, 0xfa, 0xaa, + 0xa6, 0x0, 0x0, 0xc, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0xc, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xf0, 0x0, 0x0, 0x0, 0x0, 0xc, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xe0, 0x0, + 0x0, 0x0, + + /* U+0067 "g" */ + 0x0, 0x8, 0xdf, 0xe9, 0x16, 0xf1, 0x1, 0xdf, + 0xda, 0xaf, 0xeb, 0xf2, 0xa, 0xf8, 0x0, 0x1, + 0xcf, 0xf2, 0x1f, 0xd0, 0x0, 0x0, 0x1f, 0xf2, + 0x4f, 0x80, 0x0, 0x0, 0xb, 0xf2, 0x5f, 0x70, + 0x0, 0x0, 0xa, 0xf2, 0x4f, 0x80, 0x0, 0x0, + 0xb, 0xf2, 0x1f, 0xd0, 0x0, 0x0, 0x2f, 0xf2, + 0xa, 0xfa, 0x0, 0x2, 0xdf, 0xf2, 0x1, 0xdf, + 0xfc, 0xcf, 0xec, 0xf2, 0x0, 0x8, 0xdf, 0xe9, + 0x19, 0xf2, 0x0, 0x0, 0x0, 0x0, 0xa, 0xf1, + 0x0, 0x0, 0x0, 0x0, 0xd, 0xf0, 0x2, 0x51, + 0x0, 0x0, 0x8f, 0xb0, 0xa, 0xff, 0xec, 0xce, + 0xfe, 0x20, 0x2, 0x7b, 0xdf, 0xfd, 0x91, 0x0, + + /* U+0068 "h" */ + 0x8f, 0x0, 0x0, 0x0, 0x0, 0xa, 0xf2, 0x0, + 0x0, 0x0, 0x0, 0xaf, 0x20, 0x0, 0x0, 0x0, + 0xa, 0xf2, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x20, + 0x7d, 0xfe, 0x80, 0xa, 0xf3, 0xcf, 0xec, 0xff, + 0x80, 0xaf, 0xde, 0x50, 0x1, 0xef, 0xa, 0xff, + 0x30, 0x0, 0x9, 0xf3, 0xaf, 0x90, 0x0, 0x0, + 0x8f, 0x3a, 0xf3, 0x0, 0x0, 0x8, 0xf3, 0xaf, + 0x20, 0x0, 0x0, 0x8f, 0x3a, 0xf2, 0x0, 0x0, + 0x8, 0xf3, 0xaf, 0x20, 0x0, 0x0, 0x8f, 0x3a, + 0xf2, 0x0, 0x0, 0x8, 0xf3, 0x8f, 0x0, 0x0, + 0x0, 0x6f, 0x20, + + /* U+0069 "i" */ + 0x0, 0x0, 0xbf, 0x30, 0x0, 0x0, 0x0, 0xe, + 0xf5, 0x0, 0x0, 0x0, 0x0, 0xbf, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, + 0xff, 0x30, 0x0, 0x0, 0x9a, 0xac, 0xf5, 0x0, + 0x0, 0x0, 0x0, 0x6f, 0x50, 0x0, 0x0, 0x0, + 0x6, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x6f, 0x50, + 0x0, 0x0, 0x0, 0x6, 0xf5, 0x0, 0x0, 0x0, + 0x0, 0x6f, 0x50, 0x0, 0x0, 0x0, 0x6, 0xf5, + 0x0, 0x0, 0x0, 0x0, 0x6f, 0x50, 0x0, 0x6, + 0xaa, 0xac, 0xfc, 0xaa, 0xa7, 0xaf, 0xff, 0xff, + 0xff, 0xff, 0xb0, + + /* U+006A "j" */ + 0x0, 0x0, 0x0, 0x7f, 0x60, 0x0, 0x0, 0xa, + 0xf9, 0x0, 0x0, 0x0, 0x8f, 0x70, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xff, 0xff, 0xff, 0x70, 0x7a, + 0xaa, 0xab, 0xf9, 0x0, 0x0, 0x0, 0x2f, 0x90, + 0x0, 0x0, 0x2, 0xf9, 0x0, 0x0, 0x0, 0x2f, + 0x90, 0x0, 0x0, 0x2, 0xf9, 0x0, 0x0, 0x0, + 0x2f, 0x90, 0x0, 0x0, 0x2, 0xf9, 0x0, 0x0, + 0x0, 0x2f, 0x90, 0x0, 0x0, 0x2, 0xf9, 0x0, + 0x0, 0x0, 0x2f, 0x90, 0x0, 0x0, 0x2, 0xf9, + 0x0, 0x0, 0x0, 0x4f, 0x88, 0xd5, 0x0, 0x9, + 0xf5, 0x7f, 0xfe, 0xbd, 0xfe, 0x0, 0x18, 0xdf, + 0xfb, 0x20, + + /* U+006B "k" */ + 0x2f, 0x50, 0x0, 0x0, 0x0, 0x4, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x4f, 0x70, 0x0, 0x0, 0x0, + 0x4, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x4f, 0x70, + 0x0, 0x0, 0x9e, 0x24, 0xf7, 0x0, 0x0, 0xbf, + 0xc0, 0x4f, 0x70, 0x1, 0xdf, 0xa0, 0x4, 0xf7, + 0x3, 0xef, 0x80, 0x0, 0x4f, 0x74, 0xff, 0x60, + 0x0, 0x4, 0xfc, 0xff, 0xf7, 0x0, 0x0, 0x4f, + 0xfe, 0x4d, 0xf6, 0x0, 0x4, 0xfc, 0x10, 0x2e, + 0xf5, 0x0, 0x4f, 0x70, 0x0, 0x2e, 0xf4, 0x4, + 0xf7, 0x0, 0x0, 0x3f, 0xf3, 0x2f, 0x50, 0x0, + 0x0, 0x4e, 0x60, + + /* U+006C "l" */ + 0x5f, 0xff, 0xff, 0x20, 0x0, 0x3, 0xaa, 0xad, + 0xf3, 0x0, 0x0, 0x0, 0x0, 0x8f, 0x30, 0x0, + 0x0, 0x0, 0x8, 0xf3, 0x0, 0x0, 0x0, 0x0, + 0x8f, 0x30, 0x0, 0x0, 0x0, 0x8, 0xf3, 0x0, + 0x0, 0x0, 0x0, 0x8f, 0x30, 0x0, 0x0, 0x0, + 0x8, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x8f, 0x30, + 0x0, 0x0, 0x0, 0x8, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0x30, 0x0, 0x0, 0x0, 0x8, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x8f, 0x30, 0x0, 0x8, + 0xaa, 0xad, 0xfb, 0xaa, 0xa5, 0xcf, 0xff, 0xff, + 0xff, 0xff, 0x90, + + /* U+006D "m" */ + 0x7d, 0xa, 0xfc, 0x21, 0xbf, 0xc1, 0x9f, 0xbd, + 0xbf, 0xbc, 0xdb, 0xfa, 0x9f, 0xe0, 0xc, 0xfd, + 0x0, 0xdf, 0x9f, 0x70, 0xa, 0xf6, 0x0, 0xcf, + 0x9f, 0x40, 0xa, 0xf2, 0x0, 0xcf, 0x9f, 0x20, + 0xa, 0xf1, 0x0, 0xcf, 0x9f, 0x20, 0xa, 0xf1, + 0x0, 0xcf, 0x9f, 0x20, 0xa, 0xf1, 0x0, 0xcf, + 0x9f, 0x20, 0xa, 0xf1, 0x0, 0xcf, 0x9f, 0x20, + 0xa, 0xf1, 0x0, 0xcf, 0x7f, 0x10, 0x8, 0xe0, + 0x0, 0xad, + + /* U+006E "n" */ + 0x8e, 0x0, 0x7d, 0xfe, 0x80, 0xa, 0xf1, 0xcf, + 0xca, 0xdf, 0x80, 0xaf, 0xcd, 0x30, 0x0, 0xdf, + 0xa, 0xff, 0x20, 0x0, 0x9, 0xf3, 0xaf, 0x80, + 0x0, 0x0, 0x8f, 0x3a, 0xf3, 0x0, 0x0, 0x8, + 0xf3, 0xaf, 0x20, 0x0, 0x0, 0x8f, 0x3a, 0xf2, + 0x0, 0x0, 0x8, 0xf3, 0xaf, 0x20, 0x0, 0x0, + 0x8f, 0x3a, 0xf2, 0x0, 0x0, 0x8, 0xf3, 0x8f, + 0x0, 0x0, 0x0, 0x6f, 0x20, + + /* U+006F "o" */ + 0x0, 0x5, 0xbe, 0xfd, 0x81, 0x0, 0x0, 0xaf, + 0xfd, 0xce, 0xfe, 0x30, 0x8, 0xfb, 0x10, 0x0, + 0x7f, 0xe0, 0x1f, 0xd0, 0x0, 0x0, 0x8, 0xf6, + 0x4f, 0x80, 0x0, 0x0, 0x2, 0xfb, 0x6f, 0x60, + 0x0, 0x0, 0x0, 0xfc, 0x4f, 0x80, 0x0, 0x0, + 0x2, 0xfb, 0x1f, 0xd0, 0x0, 0x0, 0x8, 0xf7, + 0x8, 0xfb, 0x10, 0x0, 0x6f, 0xe0, 0x0, 0xbf, + 0xfc, 0xce, 0xfe, 0x30, 0x0, 0x5, 0xbe, 0xfd, + 0x81, 0x0, + + /* U+0070 "p" */ + 0xac, 0x6, 0xdf, 0xea, 0x30, 0xc, 0xeb, 0xfc, + 0xab, 0xff, 0x50, 0xcf, 0xf4, 0x0, 0x3, 0xfe, + 0x1c, 0xf7, 0x0, 0x0, 0x7, 0xf7, 0xcf, 0x10, + 0x0, 0x0, 0x2f, 0xac, 0xf0, 0x0, 0x0, 0x1, + 0xfb, 0xcf, 0x20, 0x0, 0x0, 0x2f, 0xac, 0xf8, + 0x0, 0x0, 0x8, 0xf7, 0xcf, 0xf6, 0x0, 0x5, + 0xff, 0x1c, 0xf9, 0xfe, 0xbd, 0xff, 0x50, 0xcf, + 0x6, 0xcf, 0xea, 0x30, 0xc, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0xcf, 0x0, 0x0, 0x0, 0x0, 0xc, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0x0, 0x0, + 0x0, 0x0, 0x9, 0xe0, 0x0, 0x0, 0x0, 0x0, + + /* U+0071 "q" */ + 0x0, 0x8, 0xdf, 0xe9, 0x16, 0xf1, 0x1, 0xdf, + 0xda, 0xaf, 0xeb, 0xf2, 0xa, 0xf8, 0x0, 0x1, + 0xbf, 0xf2, 0x1f, 0xd0, 0x0, 0x0, 0x1f, 0xf2, + 0x4f, 0x80, 0x0, 0x0, 0xb, 0xf2, 0x5f, 0x70, + 0x0, 0x0, 0xa, 0xf2, 0x4f, 0x90, 0x0, 0x0, + 0xb, 0xf2, 0x1f, 0xd0, 0x0, 0x0, 0x2f, 0xf2, + 0xa, 0xfa, 0x0, 0x2, 0xdf, 0xf2, 0x1, 0xdf, + 0xfc, 0xcf, 0xeb, 0xf2, 0x0, 0x8, 0xdf, 0xe9, + 0x19, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x9, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x9, 0xf2, 0x0, 0x0, + 0x0, 0x0, 0x9, 0xf2, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x7, 0xf0, + + /* U+0072 "r" */ + 0x4f, 0x20, 0x7, 0xdf, 0xe7, 0x6f, 0x32, 0xdf, + 0xec, 0xe8, 0x6f, 0x5e, 0xd4, 0x0, 0x0, 0x6f, + 0xed, 0x10, 0x0, 0x0, 0x6f, 0xf3, 0x0, 0x0, + 0x0, 0x6f, 0xc0, 0x0, 0x0, 0x0, 0x6f, 0x80, + 0x0, 0x0, 0x0, 0x6f, 0x60, 0x0, 0x0, 0x0, + 0x6f, 0x50, 0x0, 0x0, 0x0, 0x6f, 0x50, 0x0, + 0x0, 0x0, 0x4f, 0x30, 0x0, 0x0, 0x0, + + /* U+0073 "s" */ + 0x2, 0xae, 0xfe, 0xc9, 0x40, 0x3, 0xff, 0xdb, + 0xce, 0xff, 0xa0, 0xaf, 0x60, 0x0, 0x3, 0x85, + 0xb, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xfa, + 0x86, 0x42, 0x0, 0x0, 0x6c, 0xff, 0xff, 0xfd, + 0x30, 0x0, 0x0, 0x23, 0x59, 0xff, 0x10, 0x0, + 0x0, 0x0, 0x9, 0xf3, 0x89, 0x30, 0x0, 0x1, + 0xdf, 0x2b, 0xff, 0xeb, 0xbc, 0xff, 0x90, 0x4, + 0x9d, 0xff, 0xfc, 0x60, 0x0, + + /* U+0074 "t" */ + 0x0, 0x6, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xf4, 0x0, 0x0, 0x0, 0x0, 0x8, 0xf4, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xf4, 0x0, 0x0, 0x0, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x4a, 0xad, + 0xfc, 0xaa, 0xaa, 0x60, 0x0, 0x8, 0xf4, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xf4, 0x0, 0x0, 0x0, + 0x0, 0x8, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xf4, 0x0, 0x0, 0x0, 0x0, 0x7, 0xf5, 0x0, + 0x0, 0x0, 0x0, 0x5, 0xfa, 0x0, 0x4, 0xb8, + 0x0, 0x0, 0xef, 0xdb, 0xdf, 0xf8, 0x0, 0x0, + 0x2a, 0xef, 0xd9, 0x20, + + /* U+0075 "u" */ + 0xbc, 0x0, 0x0, 0x0, 0x9e, 0xd, 0xe0, 0x0, + 0x0, 0xb, 0xf0, 0xde, 0x0, 0x0, 0x0, 0xbf, + 0xd, 0xe0, 0x0, 0x0, 0xb, 0xf0, 0xde, 0x0, + 0x0, 0x0, 0xbf, 0xd, 0xe0, 0x0, 0x0, 0xd, + 0xf0, 0xde, 0x0, 0x0, 0x2, 0xff, 0xc, 0xf0, + 0x0, 0x0, 0xaf, 0xf0, 0xaf, 0x40, 0x0, 0x9f, + 0xdf, 0x3, 0xff, 0xaa, 0xef, 0x59, 0xf0, 0x3, + 0xcf, 0xea, 0x20, 0x7e, 0x0, + + /* U+0076 "v" */ + 0x5e, 0x30, 0x0, 0x0, 0x0, 0xca, 0x4f, 0xa0, + 0x0, 0x0, 0x4, 0xfa, 0xd, 0xf2, 0x0, 0x0, + 0xb, 0xf3, 0x5, 0xf9, 0x0, 0x0, 0x3f, 0xb0, + 0x0, 0xef, 0x10, 0x0, 0xaf, 0x40, 0x0, 0x6f, + 0x80, 0x2, 0xfd, 0x0, 0x0, 0xe, 0xf0, 0x9, + 0xf5, 0x0, 0x0, 0x7, 0xf7, 0x1f, 0xd0, 0x0, + 0x0, 0x1, 0xfe, 0x8f, 0x60, 0x0, 0x0, 0x0, + 0x8f, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x1d, 0xf5, + 0x0, 0x0, + + /* U+0077 "w" */ + 0x3e, 0x50, 0x0, 0x0, 0x0, 0x0, 0xe8, 0x2f, + 0x90, 0x0, 0x13, 0x0, 0x3, 0xf8, 0xe, 0xd0, + 0x0, 0xcf, 0x20, 0x7, 0xf4, 0xa, 0xf1, 0x1, + 0xff, 0x80, 0xb, 0xf0, 0x6, 0xf5, 0x7, 0xfd, + 0xd0, 0xf, 0xc0, 0x2, 0xf9, 0xc, 0xd6, 0xf2, + 0x3f, 0x80, 0x0, 0xed, 0x2f, 0x71, 0xf8, 0x7f, + 0x40, 0x0, 0xaf, 0x8f, 0x20, 0xcd, 0xaf, 0x0, + 0x0, 0x6f, 0xfd, 0x0, 0x6f, 0xfc, 0x0, 0x0, + 0x2f, 0xf7, 0x0, 0x1f, 0xf8, 0x0, 0x0, 0xc, + 0xe1, 0x0, 0x9, 0xe3, 0x0, + + /* U+0078 "x" */ + 0xa, 0xe2, 0x0, 0x0, 0x7, 0xe3, 0x6, 0xfd, + 0x10, 0x0, 0x6f, 0xd1, 0x0, 0x8f, 0xc0, 0x4, + 0xfe, 0x20, 0x0, 0xa, 0xfa, 0x3f, 0xf3, 0x0, + 0x0, 0x0, 0xcf, 0xff, 0x50, 0x0, 0x0, 0x0, + 0x3f, 0xfc, 0x0, 0x0, 0x0, 0x1, 0xdf, 0xdf, + 0x70, 0x0, 0x0, 0xc, 0xf7, 0x1d, 0xf5, 0x0, + 0x0, 0xbf, 0x90, 0x2, 0xef, 0x40, 0x9, 0xfb, + 0x0, 0x0, 0x4f, 0xf2, 0xc, 0xc1, 0x0, 0x0, + 0x5, 0xe5, + + /* U+0079 "y" */ + 0x5e, 0x30, 0x0, 0x0, 0x0, 0xca, 0x4f, 0xb0, + 0x0, 0x0, 0x4, 0xfb, 0xc, 0xf3, 0x0, 0x0, + 0xc, 0xf3, 0x5, 0xfa, 0x0, 0x0, 0x4f, 0xb0, + 0x0, 0xdf, 0x20, 0x0, 0xcf, 0x30, 0x0, 0x5f, + 0xa0, 0x3, 0xfb, 0x0, 0x0, 0xd, 0xf2, 0xb, + 0xf3, 0x0, 0x0, 0x5, 0xf9, 0x3f, 0xc0, 0x0, + 0x0, 0x0, 0xdf, 0xcf, 0x40, 0x0, 0x0, 0x0, + 0x5f, 0xfc, 0x0, 0x0, 0x0, 0x0, 0xe, 0xf4, + 0x0, 0x0, 0x0, 0x0, 0x3f, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0xaf, 0x40, 0x0, 0x0, 0x0, 0x2, + 0xfc, 0x0, 0x0, 0x0, 0x0, 0xa, 0xf5, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xc0, 0x0, 0x0, 0x0, + + /* U+007A "z" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0x15, 0xaa, 0xaa, + 0xaa, 0xff, 0xd0, 0x0, 0x0, 0x0, 0x6f, 0xe1, + 0x0, 0x0, 0x0, 0x4f, 0xf2, 0x0, 0x0, 0x0, + 0x3f, 0xf4, 0x0, 0x0, 0x0, 0x2e, 0xf5, 0x0, + 0x0, 0x0, 0x1d, 0xf7, 0x0, 0x0, 0x0, 0xc, + 0xf9, 0x0, 0x0, 0x0, 0xb, 0xfa, 0x0, 0x0, + 0x0, 0x9, 0xff, 0xba, 0xaa, 0xaa, 0xa1, 0xcf, + 0xff, 0xff, 0xff, 0xff, 0x30, + + /* U+007B "{" */ + 0x0, 0x0, 0x0, 0x48, 0xa4, 0x0, 0x0, 0x1c, + 0xff, 0xf7, 0x0, 0x0, 0xaf, 0xa2, 0x0, 0x0, + 0x0, 0xfe, 0x0, 0x0, 0x0, 0x1, 0xfb, 0x0, + 0x0, 0x0, 0x0, 0xfb, 0x0, 0x0, 0x0, 0x1, + 0xfa, 0x0, 0x0, 0x0, 0x5, 0xf7, 0x0, 0x0, + 0x1, 0x5e, 0xd0, 0x0, 0x0, 0xcf, 0xf8, 0x0, + 0x0, 0x0, 0x8c, 0xee, 0x50, 0x0, 0x0, 0x0, + 0xa, 0xf4, 0x0, 0x0, 0x0, 0x1, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x0, 0x0, + 0xfb, 0x0, 0x0, 0x0, 0x1, 0xfb, 0x0, 0x0, + 0x0, 0x0, 0xfd, 0x0, 0x0, 0x0, 0x0, 0xcf, + 0x60, 0x0, 0x0, 0x0, 0x3f, 0xfd, 0xb4, 0x0, + 0x0, 0x2, 0xae, 0xf7, + + /* U+007C "|" */ + 0x36, 0xa, 0xf1, 0xbf, 0x1b, 0xf1, 0xbf, 0x1b, + 0xf1, 0xbf, 0x1b, 0xf1, 0xbf, 0x1b, 0xf1, 0xbf, + 0x1b, 0xf1, 0xbf, 0x1b, 0xf1, 0xbf, 0x1b, 0xf1, + 0xbf, 0x1b, 0xf1, 0xbf, 0x1b, 0xf1, 0x8e, 0x0, + + /* U+007D "}" */ + 0x19, 0x96, 0x10, 0x0, 0x0, 0x1, 0xff, 0xff, + 0x50, 0x0, 0x0, 0x0, 0x16, 0xff, 0x10, 0x0, + 0x0, 0x0, 0x8, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x4f, 0x70, 0x0, 0x0, 0x0, 0x4, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x4f, 0x70, 0x0, 0x0, 0x0, + 0x1, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x7, 0xf8, + 0x20, 0x0, 0x0, 0x0, 0x4, 0xef, 0xf3, 0x0, + 0x0, 0x2, 0xbf, 0xca, 0x10, 0x0, 0x0, 0xee, + 0x20, 0x0, 0x0, 0x0, 0x4f, 0x70, 0x0, 0x0, + 0x0, 0x5, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x5f, + 0x60, 0x0, 0x0, 0x0, 0x4, 0xf7, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0x60, 0x0, 0x0, 0x0, 0x2e, + 0xf3, 0x0, 0x0, 0x1a, 0xcf, 0xf9, 0x0, 0x0, + 0x1, 0xff, 0xc5, 0x0, 0x0, 0x0, + + /* U+007E "~" */ + 0x0, 0x7c, 0xc6, 0x0, 0x0, 0x20, 0xa, 0xff, + 0xff, 0xd4, 0x5, 0xf8, 0x2f, 0xa1, 0x2a, 0xff, + 0xff, 0xf2, 0x4, 0x0, 0x0, 0x4c, 0xfc, 0x30, + + /* U+00B0 "°" */ + 0x0, 0x17, 0x83, 0x0, 0x3, 0xff, 0xff, 0x80, + 0xd, 0xe3, 0x1b, 0xf2, 0x1f, 0x80, 0x3, 0xf6, + 0xf, 0xb0, 0x6, 0xf5, 0x8, 0xfc, 0xaf, 0xd0, + 0x0, 0x8e, 0xfa, 0x10, + + /* U+2022 "•" */ + 0x19, 0xbc, 0xa5, 0x7f, 0xff, 0xfe, 0x8f, 0xff, + 0xfe, 0x8f, 0xff, 0xfe, 0x8f, 0xff, 0xfe, 0x3d, + 0xff, 0xe8, + + /* U+E0B4 "" */ + 0x0, 0x5f, 0xc0, 0xb, 0xf5, 0x0, 0x0, 0x0, + 0xb, 0xff, 0x33, 0xff, 0xb0, 0x0, 0x0, 0x0, + 0xcf, 0xf4, 0x3f, 0xfc, 0x0, 0x0, 0x6, 0xff, + 0xff, 0xff, 0xff, 0xe6, 0x0, 0x0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0x0, 0xf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf9, 0x0, 0xff, 0xf0, 0x0, + 0x0, 0x7, 0xff, 0xf2, 0xf, 0xff, 0x0, 0x0, + 0x0, 0xb, 0xff, 0x50, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0x8f, 0xf7, 0xf, 0xff, 0x0, 0x0, 0x0, + 0xd, 0xff, 0x50, 0xff, 0xf4, 0x44, 0x44, 0x5b, + 0xff, 0xf1, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfb, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfa, 0xf, 0xff, 0xbb, 0xbb, 0xbb, 0xbe, 0xff, + 0xf6, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x9, 0xff, + 0xcf, 0xff, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xff, + 0xff, 0xf0, 0x0, 0x0, 0x0, 0x2, 0xff, 0xef, + 0xff, 0x0, 0x0, 0x0, 0x2, 0xcf, 0xfb, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x5e, 0xff, + 0xff, 0xff, 0xff, 0xeb, 0x30, 0x0, 0xc, 0xff, + 0x43, 0xff, 0xc0, 0x0, 0x0, 0x0, 0xbf, 0xf3, + 0x3f, 0xfb, 0x0, 0x0, 0x0, 0x5, 0xfc, 0x0, + 0xbf, 0x50, 0x0, 0x0, + + /* U+F001 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x7c, 0xf8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x49, 0xef, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x16, 0xaf, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x7c, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x19, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0xdf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0xa5, 0xf, 0xff, 0x0, 0x0, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xd8, 0x30, 0x0, 0xf, 0xff, + 0x0, 0x0, 0x0, 0xff, 0xff, 0xfc, 0x72, 0x0, + 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, 0xff, + 0xf5, 0x10, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, + 0x0, 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, + 0x0, 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, 0x0, + 0x1, 0x57, 0x5f, 0xff, 0x0, 0x0, 0x0, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0x8f, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, 0x7, + 0xff, 0xff, 0xff, 0xff, 0x0, 0x15, 0x75, 0xff, + 0xf0, 0x0, 0x0, 0xe, 0xff, 0xff, 0xff, 0xff, + 0x8, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0, 0xf, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, + 0xf0, 0x0, 0x0, 0xb, 0xff, 0xff, 0xff, 0xfb, + 0xef, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x2, + 0xef, 0xff, 0xff, 0xe2, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0x18, 0xdf, 0xd8, 0x10, + 0xbf, 0xff, 0xff, 0xff, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2e, 0xff, 0xff, 0xfe, + 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x8d, 0xfd, 0x81, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+F008 "" */ + 0x0, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x42, 0x0, 0x1c, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, + 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfa, 0xff, 0xeb, 0xcf, 0xff, + 0xdb, 0xbb, 0xbb, 0xbc, 0xff, 0xfc, 0xbe, 0xff, + 0xff, 0x40, 0xe, 0xf9, 0x0, 0x0, 0x0, 0x0, + 0x9f, 0xf0, 0x4, 0xff, 0xff, 0x40, 0xe, 0xf6, + 0x0, 0x0, 0x0, 0x0, 0x5f, 0xe0, 0x4, 0xff, + 0xff, 0x94, 0x5f, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x5f, 0xf6, 0x49, 0xff, 0xff, 0xff, 0xff, 0xf6, + 0x0, 0x0, 0x0, 0x0, 0x5f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf7, 0x0, 0x0, 0x0, 0x0, + 0x6f, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xcf, 0xfe, + 0x64, 0x44, 0x44, 0x45, 0xef, 0xfc, 0xbe, 0xff, + 0xff, 0x40, 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x4, 0xff, 0xff, 0x40, 0xe, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x4, 0xff, + 0xff, 0x94, 0x5f, 0xff, 0xdb, 0xbb, 0xbb, 0xbc, + 0xff, 0xf6, 0x49, 0xff, 0xff, 0xff, 0xff, 0xf9, + 0x0, 0x0, 0x0, 0x0, 0x9f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x5f, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xcf, 0xf6, + 0x0, 0x0, 0x0, 0x0, 0x5f, 0xfc, 0xbe, 0xff, + 0xff, 0x40, 0xe, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x5f, 0xf0, 0x4, 0xff, 0xff, 0x40, 0xe, 0xf7, + 0x0, 0x0, 0x0, 0x0, 0x6f, 0xe0, 0x4, 0xff, + 0xff, 0x94, 0x5f, 0xfe, 0x64, 0x44, 0x44, 0x45, + 0xef, 0xf6, 0x49, 0xff, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf5, 0x3, 0x9b, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x30, + + /* U+F00B "" */ + 0x0, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x42, 0x0, 0x1c, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, + 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfb, 0xbb, 0xff, + 0xfb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xff, + 0xff, 0xf0, 0x0, 0xff, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0xff, 0xff, 0xf0, 0x0, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, + 0xff, 0xf4, 0x44, 0xff, 0xf4, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xbb, 0xff, + 0xfb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xff, + 0xff, 0xf0, 0x0, 0xff, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0xff, 0xff, 0xf0, 0x0, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, + 0xff, 0xf4, 0x44, 0xff, 0xf4, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xbb, 0xff, + 0xfb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xff, + 0xff, 0xf0, 0x0, 0xff, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0xff, 0xff, 0xf0, 0x0, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, + 0xff, 0xf4, 0x44, 0xff, 0xf4, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x4f, 0xff, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf5, 0x3, 0x9b, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x30, + + /* U+F00C "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xaf, 0xf5, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xff, + 0xf5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xaf, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xff, 0xfa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0xff, + 0xa0, 0x0, 0x5, 0x50, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xff, 0xfa, 0x0, 0x0, 0x5f, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x9f, 0xff, 0xa0, 0x0, 0x0, + 0x5f, 0xff, 0xa0, 0x0, 0x0, 0x9, 0xff, 0xfa, + 0x0, 0x0, 0x0, 0xa, 0xff, 0xf9, 0x0, 0x0, + 0x9f, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, 0xaf, + 0xff, 0x90, 0x9, 0xff, 0xfa, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xa, 0xff, 0xf9, 0x9f, 0xff, 0xa0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0xff, + 0xff, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xff, 0xff, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F00D "" */ + 0x15, 0x10, 0x0, 0x0, 0x0, 0x0, 0x15, 0x1d, + 0xfe, 0x20, 0x0, 0x0, 0x0, 0x2e, 0xfd, 0xef, + 0xfd, 0x10, 0x0, 0x0, 0x1d, 0xff, 0xe5, 0xff, + 0xfd, 0x10, 0x0, 0x1d, 0xff, 0xf5, 0x5, 0xff, + 0xfd, 0x10, 0x1d, 0xff, 0xf5, 0x0, 0x5, 0xff, + 0xfc, 0x2c, 0xff, 0xf5, 0x0, 0x0, 0x6, 0xff, + 0xff, 0xff, 0xf6, 0x0, 0x0, 0x0, 0x6, 0xff, + 0xff, 0xf6, 0x0, 0x0, 0x0, 0x0, 0xd, 0xff, + 0xfd, 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, 0xff, + 0xfc, 0x0, 0x0, 0x0, 0xb, 0xff, 0xfb, 0xff, + 0xfb, 0x0, 0x0, 0xb, 0xff, 0xf8, 0x8, 0xff, + 0xfb, 0x0, 0xb, 0xff, 0xf8, 0x0, 0x8, 0xff, + 0xfb, 0xa, 0xff, 0xf9, 0x0, 0x0, 0x9, 0xff, + 0xfa, 0xff, 0xf9, 0x0, 0x0, 0x0, 0x9, 0xff, + 0xf8, 0xf9, 0x0, 0x0, 0x0, 0x0, 0x9, 0xf8, + + /* U+F011 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb, 0xff, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xbf, 0xf4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6, 0xfc, 0x0, 0xb, + 0xff, 0x40, 0x4, 0xfd, 0x10, 0x0, 0x0, 0x6, + 0xff, 0xf3, 0x0, 0xbf, 0xf4, 0x0, 0x9f, 0xfd, + 0x10, 0x0, 0x3, 0xff, 0xfc, 0x0, 0xb, 0xff, + 0x40, 0x3, 0xff, 0xfc, 0x0, 0x0, 0xcf, 0xfc, + 0x0, 0x0, 0xbf, 0xf4, 0x0, 0x4, 0xff, 0xf6, + 0x0, 0x5f, 0xff, 0x20, 0x0, 0xb, 0xff, 0x40, + 0x0, 0x7, 0xff, 0xe0, 0xb, 0xff, 0x80, 0x0, + 0x0, 0xbf, 0xf4, 0x0, 0x0, 0xe, 0xff, 0x50, + 0xff, 0xf2, 0x0, 0x0, 0xb, 0xff, 0x40, 0x0, + 0x0, 0x8f, 0xf9, 0x2f, 0xfe, 0x0, 0x0, 0x0, + 0xbf, 0xf4, 0x0, 0x0, 0x4, 0xff, 0xc3, 0xff, + 0xc0, 0x0, 0x0, 0xb, 0xff, 0x40, 0x0, 0x0, + 0x3f, 0xfd, 0x3f, 0xfc, 0x0, 0x0, 0x0, 0x9f, + 0xf2, 0x0, 0x0, 0x3, 0xff, 0xd1, 0xff, 0xe0, + 0x0, 0x0, 0x0, 0x64, 0x0, 0x0, 0x0, 0x5f, + 0xfb, 0xe, 0xff, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9, 0xff, 0x80, 0xaf, 0xf9, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, 0xf4, + 0x4, 0xff, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0xfd, 0x0, 0xc, 0xff, 0xd0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5f, 0xff, 0x60, 0x0, + 0x2f, 0xff, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x6f, + 0xff, 0xb0, 0x0, 0x0, 0x5f, 0xff, 0xf9, 0x30, + 0x0, 0x5, 0xcf, 0xff, 0xd1, 0x0, 0x0, 0x0, + 0x5f, 0xff, 0xff, 0xfd, 0xef, 0xff, 0xff, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x2c, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xae, 0xff, 0xff, 0xd8, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x22, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+F013 "" */ + 0x0, 0x0, 0x0, 0x0, 0x7, 0xdf, 0xfd, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2f, 0xff, 0xff, 0xf2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7f, 0xff, 0xff, 0xf7, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x5f, 0xc7, 0x3c, 0xff, 0xff, 0xff, 0xff, + 0xc3, 0x7c, 0xf5, 0x0, 0x1, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, + 0xa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xa0, 0x1f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0x95, 0x59, 0xff, + 0xff, 0xff, 0xff, 0xf2, 0x6, 0xff, 0xff, 0xff, + 0xf4, 0x0, 0x0, 0x4f, 0xff, 0xff, 0xff, 0x60, + 0x0, 0x4f, 0xff, 0xff, 0x90, 0x0, 0x0, 0x9, + 0xff, 0xff, 0xf4, 0x0, 0x0, 0xf, 0xff, 0xff, + 0x50, 0x0, 0x0, 0x5, 0xff, 0xff, 0xf0, 0x0, + 0x0, 0xf, 0xff, 0xff, 0x50, 0x0, 0x0, 0x5, + 0xff, 0xff, 0xf0, 0x0, 0x0, 0x4f, 0xff, 0xff, + 0x90, 0x0, 0x0, 0x9, 0xff, 0xff, 0xf4, 0x0, + 0x5, 0xff, 0xff, 0xff, 0xf4, 0x0, 0x0, 0x4f, + 0xff, 0xff, 0xff, 0x60, 0x2f, 0xff, 0xff, 0xff, + 0xff, 0x95, 0x59, 0xff, 0xff, 0xff, 0xff, 0xf2, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf1, 0xa, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, + 0x1, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0x10, 0x0, 0x5f, 0xc7, 0x3c, + 0xff, 0xff, 0xff, 0xff, 0xc3, 0x7c, 0xf5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff, 0xff, 0xf7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2f, 0xff, 0xff, 0xf2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xdf, 0xfd, 0x70, 0x0, 0x0, 0x0, 0x0, + + /* U+F015 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x9f, 0x90, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1b, 0xff, 0xfb, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xdf, + 0xff, 0xff, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3e, 0xff, 0xff, 0xff, + 0xfe, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x90, 0x0, 0x0, 0x0, 0x1b, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfb, 0x0, 0x0, 0x1, 0xdf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xd1, 0x0, 0x3e, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x20, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xd0, 0x27, 0x8f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x87, 0x10, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, + 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0xf, + 0xff, 0xff, 0xff, 0xfa, 0x88, 0x8a, 0xff, 0xff, + 0xff, 0xff, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, + 0xff, 0xa0, 0x0, 0x0, 0xaf, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, 0x80, + 0x0, 0x0, 0x8f, 0xff, 0xff, 0xff, 0x0, 0x0, + 0x0, 0xf, 0xff, 0xff, 0xff, 0x80, 0x0, 0x0, + 0x8f, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0xf, + 0xff, 0xff, 0xff, 0x80, 0x0, 0x0, 0x8f, 0xff, + 0xff, 0xff, 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, + 0xff, 0x80, 0x0, 0x0, 0x8f, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0xe, 0xff, 0xff, 0xff, 0x60, + 0x0, 0x0, 0x6f, 0xff, 0xff, 0xfe, 0x0, 0x0, + 0x0, 0x5, 0xef, 0xff, 0xfb, 0x0, 0x0, 0x0, + 0xb, 0xff, 0xff, 0xe5, 0x0, 0x0, + + /* U+F019 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0xd2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0xd3, + 0x0, 0x7f, 0xf7, 0x0, 0x3d, 0xd2, 0x0, 0x0, + 0x0, 0x0, 0x7f, 0xfe, 0x30, 0x7f, 0xf7, 0x3, + 0xff, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x2f, 0xff, + 0xe3, 0x7f, 0xf7, 0x3e, 0xff, 0xf2, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xff, 0xfe, 0xaf, 0xfa, 0xef, + 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, + 0xff, 0xff, 0xff, 0xff, 0xf3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xff, 0xff, 0xff, 0xff, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3f, 0xff, 0xff, 0xf3, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x67, 0x77, 0x77, 0x3, 0xff, 0xff, 0x30, + 0x77, 0x77, 0x76, 0x10, 0x3e, 0xff, 0xff, 0xff, + 0xb0, 0x3d, 0xd3, 0xb, 0xff, 0xff, 0xff, 0xe3, + 0xcf, 0xff, 0xff, 0xff, 0xfb, 0x10, 0x1, 0xbf, + 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe9, 0x9e, 0xff, 0xff, 0xf9, 0x4e, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf4, 0xc, 0xff, 0xef, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xcf, 0xfe, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf8, 0x8, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x80, + + /* U+F01C "" */ + 0x0, 0x0, 0x3, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x30, 0x0, 0x0, 0x0, 0x4, 0xef, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x40, 0x0, + 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x0, 0x0, 0x5f, 0xfe, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xef, 0xf5, 0x0, + 0x0, 0x9f, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0xf9, 0x0, 0x0, 0xdf, 0xf3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0xfd, 0x0, + 0x1, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xff, 0x10, 0x5, 0xff, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xff, 0x50, + 0x9, 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7, 0xff, 0x90, 0xd, 0xff, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xff, 0xd0, + 0x1f, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xff, 0xf1, 0x5f, 0xfb, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xf5, + 0x9f, 0xfa, 0x44, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x44, 0xaf, 0xf9, 0xdf, 0xff, 0xff, 0xe2, + 0x0, 0x0, 0x0, 0x0, 0x2e, 0xff, 0xff, 0xfd, + 0xff, 0xff, 0xff, 0xfa, 0x0, 0x0, 0x0, 0x0, + 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x84, 0x44, 0x44, 0x48, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf5, 0x3, 0x9b, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x30, + + /* U+F021 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x32, 0x0, + 0x0, 0x0, 0x3, 0x10, 0x0, 0x0, 0x0, 0x4, + 0xaf, 0xff, 0xff, 0xfa, 0x30, 0x0, 0x9f, 0xe0, + 0x0, 0x0, 0x1, 0xbf, 0xff, 0xff, 0xff, 0xff, + 0xfa, 0x10, 0xcf, 0xf3, 0x0, 0x0, 0x3e, 0xff, + 0xff, 0xec, 0xce, 0xff, 0xff, 0xd2, 0xcf, 0xf3, + 0x0, 0x1, 0xef, 0xff, 0x92, 0x0, 0x0, 0x3a, + 0xff, 0xfe, 0xef, 0xf3, 0x0, 0xc, 0xff, 0xe4, + 0x0, 0x0, 0x0, 0x0, 0x5f, 0xff, 0xff, 0xf3, + 0x0, 0x5f, 0xff, 0x30, 0x0, 0x0, 0x0, 0x3, + 0x48, 0xff, 0xff, 0xf3, 0x0, 0xdf, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x9f, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0xff, 0xe0, 0x0, 0x0, 0x0, 0x0, 0xbf, + 0xff, 0xff, 0xff, 0xf2, 0x0, 0x4a, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x3a, 0xbb, 0xbb, 0xbb, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x44, 0x44, 0x44, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x30, 0x0, 0xc, 0xff, 0xff, 0xff, + 0xfb, 0x0, 0x0, 0x0, 0x0, 0x9, 0xfe, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xfd, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0xff, 0x10, 0x1f, 0xff, 0xff, 0xcb, + 0xb4, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xfa, 0x0, + 0x1f, 0xff, 0xff, 0xc1, 0x0, 0x0, 0x0, 0x0, + 0x9, 0xff, 0xf3, 0x0, 0x1f, 0xff, 0xff, 0xfe, + 0x40, 0x0, 0x0, 0x2, 0xbf, 0xff, 0x70, 0x0, + 0x1f, 0xfe, 0x6f, 0xff, 0xfc, 0x75, 0x56, 0xaf, + 0xff, 0xfa, 0x0, 0x0, 0x1f, 0xfe, 0x4, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0, 0x0, + 0xf, 0xfd, 0x0, 0x19, 0xff, 0xff, 0xff, 0xff, + 0xc3, 0x0, 0x0, 0x0, 0x5, 0xa4, 0x0, 0x0, + 0x15, 0x9a, 0xb9, 0x72, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, + + /* U+F026 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0xfb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2e, 0xff, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0x4f, 0xff, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x5f, 0xff, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0x7f, 0xff, 0xff, 0xff, 0x0, 0x24, 0x44, + 0x9f, 0xff, 0xff, 0xff, 0xf1, 0xcf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x39, 0xbb, 0xbe, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x1d, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0xb, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xff, 0xff, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0x8, 0xff, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7, 0xff, 0xe0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xa4, + + /* U+F027 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0xfb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0xff, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x4f, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0xff, + 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7f, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, + 0x24, 0x44, 0x9f, 0xff, 0xff, 0xff, 0xf0, 0x0, + 0x0, 0x1, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0, 0x2b, 0x50, 0xaf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0x6, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xd, + 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x0, 0x5f, 0xef, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0, 0x5, 0xfe, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0xdf, + 0xbd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x6f, 0xf3, 0x5f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x2, 0xb5, 0x0, 0x39, 0xbb, + 0xbe, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1d, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xff, + 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0xff, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x4, 0xa4, 0x0, 0x0, 0x0, + + /* U+F028 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, + 0x0, 0x0, 0x5, 0xa1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xdf, 0xb0, 0x0, 0x0, + 0x0, 0xc, 0xfd, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2e, 0xff, 0xf0, 0x0, 0x0, 0x0, + 0x3, 0xff, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x2, 0x0, + 0x3f, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, + 0xff, 0xff, 0xf0, 0x0, 0x0, 0x8f, 0xa0, 0x6, + 0xff, 0x40, 0x0, 0x0, 0x0, 0x7, 0xff, 0xff, + 0xff, 0xf0, 0x0, 0x0, 0x6f, 0xf9, 0x0, 0xbf, + 0xc0, 0x0, 0x24, 0x44, 0x9f, 0xff, 0xff, 0xff, + 0xf0, 0x0, 0x0, 0x8, 0xff, 0x40, 0x3f, 0xf3, + 0x1c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x2, 0xb5, 0x0, 0xcf, 0xc0, 0xc, 0xf8, 0xaf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x6, + 0xff, 0x30, 0x4f, 0xf1, 0x8, 0xfb, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0xdf, + 0xb0, 0xf, 0xf5, 0x5, 0xfe, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x5f, 0xe0, + 0xd, 0xf7, 0x4, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0x0, 0x5f, 0xe0, 0xd, + 0xf7, 0x4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x0, 0xdf, 0xb0, 0xf, 0xf5, + 0x5, 0xfe, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x6, 0xff, 0x30, 0x4f, 0xf1, 0x8, + 0xfb, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x2, 0xb5, 0x0, 0xcf, 0xc0, 0xc, 0xf8, + 0x3, 0x9b, 0xbb, 0xef, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x8, 0xff, 0x40, 0x3f, 0xf3, 0x0, + 0x0, 0x0, 0x1d, 0xff, 0xff, 0xff, 0xf0, 0x0, + 0x0, 0x6f, 0xf9, 0x0, 0xbf, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0xbf, 0xff, 0xff, 0xf0, 0x0, 0x0, + 0x8f, 0xa0, 0x6, 0xff, 0x40, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x2, + 0x0, 0x3f, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x3, + 0xff, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xff, 0xe0, 0x0, 0x0, 0x0, 0xc, 0xfe, + 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4a, 0x40, 0x0, 0x0, 0x0, 0x5, 0xa2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F03E "" */ + 0x0, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x42, 0x0, 0x1c, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, + 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xec, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf9, 0x0, 0x2f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0x0, 0x9, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf1, 0x0, 0x9, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x0, 0x3f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xf9, 0x5e, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xc0, 0x4, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x0, + 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf6, 0x0, 0x0, 0xe, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xed, 0xff, 0xb0, 0x0, 0x0, + 0x4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x10, + 0xbe, 0x10, 0x0, 0x0, 0x0, 0x9f, 0xff, 0xff, + 0xff, 0xff, 0xf2, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x0, 0xd, 0xff, 0xff, 0xff, 0xff, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xff, 0xff, + 0xff, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8f, 0xff, 0xff, 0xf1, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xff, + 0xff, 0xf9, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x9f, 0xff, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf5, 0x3, 0x9b, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x30, + + /* U+F043 "" */ + 0x0, 0x0, 0x0, 0x0, 0x77, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0xff, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xdf, 0xff, + 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff, + 0xff, 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, 0x2f, + 0xff, 0xff, 0xff, 0xf2, 0x0, 0x0, 0x0, 0x0, + 0xbf, 0xff, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, + 0x5, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50, 0x0, + 0x0, 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, + 0x0, 0x0, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf6, 0x0, 0x0, 0xdf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0x0, 0x5, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x50, 0xb, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xb0, 0xf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x3f, + 0xfc, 0xa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, + 0x1f, 0xff, 0x6, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf1, 0xc, 0xff, 0x60, 0xcf, 0xff, 0xff, 0xff, + 0xff, 0xc0, 0x6, 0xff, 0xf3, 0x7, 0xcf, 0xff, + 0xff, 0xff, 0x60, 0x0, 0xdf, 0xff, 0x71, 0x5, + 0xff, 0xff, 0xfd, 0x0, 0x0, 0x2e, 0xff, 0xff, + 0xdf, 0xff, 0xff, 0xe2, 0x0, 0x0, 0x1, 0xcf, + 0xff, 0xff, 0xff, 0xfc, 0x10, 0x0, 0x0, 0x0, + 0x6, 0xcf, 0xff, 0xfc, 0x50, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x0, + + /* U+F048 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xf8, 0x0, 0x0, 0x0, 0x0, 0x9, 0xf8, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0x1c, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x2d, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0x0, + 0x0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, + 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1, 0xcf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x2d, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0x1c, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0, 0x9, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x0, 0x7, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x0, 0x0, 0x4, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x0, 0x0, 0x2, 0xdf, 0xff, 0xff, + 0xff, 0x0, 0x0, 0x0, 0x1, 0xcf, 0xff, 0x8f, + 0x80, 0x0, 0x0, 0x0, 0x0, 0x9f, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F04B "" */ + 0x5, 0x72, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9f, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xff, 0xff, 0xfd, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xfa, 0x10, + 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, + 0xf7, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xd3, 0x0, 0x0, 0x0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x91, 0x0, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x60, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0x30, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x30, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x60, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xa1, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x0, 0x0, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x0, 0x0, + 0x0, 0x0, 0xff, 0xff, 0xff, 0xfa, 0x10, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xff, 0xfd, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x9f, 0xff, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x72, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F04C "" */ + 0x3c, 0xff, 0xc3, 0x0, 0x3, 0xcf, 0xfc, 0x3c, + 0xff, 0xff, 0xc0, 0x0, 0xcf, 0xff, 0xfc, 0xff, + 0xff, 0xff, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, + 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x0, 0xf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0x0, 0xff, 0xff, 0xff, + 0xcf, 0xff, 0xfc, 0x0, 0xc, 0xff, 0xff, 0xc3, + 0xcf, 0xfc, 0x30, 0x0, 0x3c, 0xff, 0xc3, + + /* U+F04D "" */ + 0x8, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x80, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf8, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf8, 0x8, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0x80, + + /* U+F051 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xf9, 0x0, 0x0, 0x0, 0x0, 0x8, 0xf8, 0xff, + 0xfc, 0x10, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, + 0xfe, 0x30, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, + 0xff, 0x50, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x70, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xa0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xc1, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x10, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x0, 0xf, + 0xff, 0xff, 0xff, 0xff, 0xf7, 0x0, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xf5, 0x0, 0x0, 0xf, 0xff, + 0xff, 0xff, 0xe3, 0x0, 0x0, 0x0, 0xff, 0xff, + 0xff, 0xc1, 0x0, 0x0, 0x0, 0xf, 0xff, 0x8f, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x8f, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F052 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x37, 0x30, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6f, 0xff, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5f, 0xff, 0xff, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xff, + 0xff, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x20, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2e, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x20, 0x0, 0x0, 0x0, 0x0, 0x1e, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x10, 0x0, + 0x0, 0x0, 0x1d, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfc, 0x0, 0x0, 0x0, 0xc, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x0, + 0xb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfb, 0x0, 0x9, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0x0, 0x3d, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3c, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x30, 0xc, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfc, 0x0, 0xef, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x8, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf8, 0x0, 0x4, 0x78, 0x88, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x74, 0x0, + + /* U+F053 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7f, 0xf4, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0xff, 0x60, 0x0, 0x0, 0x0, 0x7f, + 0xff, 0xc0, 0x0, 0x0, 0x0, 0x7f, 0xff, 0xc1, + 0x0, 0x0, 0x0, 0x7f, 0xff, 0xc1, 0x0, 0x0, + 0x0, 0x7f, 0xff, 0xc1, 0x0, 0x0, 0x0, 0x7f, + 0xff, 0xc0, 0x0, 0x0, 0x0, 0x7f, 0xff, 0xc0, + 0x0, 0x0, 0x0, 0x7f, 0xff, 0xc0, 0x0, 0x0, + 0x0, 0x4f, 0xff, 0xc0, 0x0, 0x0, 0x0, 0x6, + 0xff, 0xf7, 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, + 0xf6, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xff, 0xf6, + 0x0, 0x0, 0x0, 0x0, 0x1c, 0xff, 0xf6, 0x0, + 0x0, 0x0, 0x0, 0x1c, 0xff, 0xf6, 0x0, 0x0, + 0x0, 0x0, 0x1c, 0xff, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0x1c, 0xff, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x1c, 0xff, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x1c, + 0xff, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x19, 0x90, + + /* U+F054 "" */ + 0x2, 0x20, 0x0, 0x0, 0x0, 0x0, 0x4, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xff, 0x60, + 0x0, 0x0, 0x0, 0x0, 0xcf, 0xff, 0x60, 0x0, + 0x0, 0x0, 0x1, 0xcf, 0xff, 0x60, 0x0, 0x0, + 0x0, 0x1, 0xcf, 0xff, 0x60, 0x0, 0x0, 0x0, + 0x1, 0xcf, 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, + 0xcf, 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, 0xcf, + 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xff, 0x40, + 0x0, 0x0, 0x0, 0x7, 0xff, 0xf6, 0x0, 0x0, + 0x0, 0x6, 0xff, 0xfc, 0x0, 0x0, 0x0, 0x6, + 0xff, 0xfc, 0x10, 0x0, 0x0, 0x6, 0xff, 0xfc, + 0x10, 0x0, 0x0, 0x6, 0xff, 0xfc, 0x10, 0x0, + 0x0, 0x6, 0xff, 0xfc, 0x10, 0x0, 0x0, 0x6, + 0xff, 0xfc, 0x10, 0x0, 0x0, 0x6, 0xff, 0xfc, + 0x10, 0x0, 0x0, 0x4, 0xff, 0xfc, 0x10, 0x0, + 0x0, 0x0, 0x6f, 0xfc, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x99, 0x10, 0x0, 0x0, 0x0, 0x0, + + /* U+F067 "" */ + 0x0, 0x0, 0x0, 0x0, 0x8, 0xf8, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11, 0x11, + 0x1f, 0xff, 0x11, 0x11, 0x11, 0x10, 0x0, 0xdf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xd0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x30, 0xbf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, + 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x9f, 0x90, 0x0, 0x0, + 0x0, 0x0, + + /* U+F068 "" */ + 0x0, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x10, 0x0, 0xdf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xd0, 0x3f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, + 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb0, + + /* U+F06E "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x79, 0xa9, + 0x74, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x8e, 0xff, 0xff, 0xff, 0xfe, + 0x81, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, 0xff, 0xfd, + 0x73, 0x13, 0x7d, 0xff, 0xff, 0xfc, 0x0, 0x0, + 0x0, 0x0, 0xb, 0xff, 0xff, 0xf7, 0x0, 0x0, + 0x0, 0x7, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, + 0x9, 0xff, 0xff, 0xf6, 0x0, 0x0, 0x55, 0x10, + 0x6, 0xff, 0xff, 0xf9, 0x0, 0x0, 0x4, 0xff, + 0xff, 0xfb, 0x0, 0x0, 0x9, 0xff, 0x50, 0xb, + 0xff, 0xff, 0xf4, 0x0, 0x0, 0xdf, 0xff, 0xff, + 0x30, 0x0, 0x0, 0x9f, 0xff, 0x30, 0x3f, 0xff, + 0xff, 0xd0, 0x0, 0x6f, 0xff, 0xff, 0xf0, 0x0, + 0x0, 0x1e, 0xff, 0xfb, 0x0, 0xff, 0xff, 0xff, + 0x70, 0xd, 0xff, 0xff, 0xfc, 0x0, 0x30, 0x3c, + 0xff, 0xff, 0xf0, 0xc, 0xff, 0xff, 0xfe, 0x0, + 0xdf, 0xff, 0xff, 0xc0, 0xf, 0xff, 0xff, 0xff, + 0xff, 0x0, 0xcf, 0xff, 0xff, 0xe0, 0x6, 0xff, + 0xff, 0xff, 0x0, 0xbf, 0xff, 0xff, 0xff, 0xb0, + 0xf, 0xff, 0xff, 0xf7, 0x0, 0xd, 0xff, 0xff, + 0xf3, 0x3, 0xff, 0xff, 0xff, 0xf3, 0x3, 0xff, + 0xff, 0xfd, 0x0, 0x0, 0x4f, 0xff, 0xff, 0xb0, + 0x5, 0xff, 0xff, 0xf5, 0x0, 0xbf, 0xff, 0xff, + 0x40, 0x0, 0x0, 0x9f, 0xff, 0xff, 0x60, 0x1, + 0x57, 0x51, 0x0, 0x6f, 0xff, 0xff, 0x90, 0x0, + 0x0, 0x0, 0xbf, 0xff, 0xff, 0x70, 0x0, 0x0, + 0x0, 0x7f, 0xff, 0xff, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xff, 0xff, 0xd7, 0x31, 0x37, 0xdf, + 0xff, 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6e, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x60, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0xff, + 0xff, 0xff, 0xff, 0xe8, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x47, 0x9a, + 0x97, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F070 "" */ + 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xd, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xff, 0x90, 0x0, 0x0, 0x0, 0x15, 0x89, + 0x98, 0x61, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xbf, 0xfc, 0x10, 0x0, 0x5c, 0xff, 0xff, + 0xff, 0xff, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0xff, 0xe4, 0x2c, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xb1, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2, 0xdf, 0xff, 0xff, 0xfa, 0x42, + 0x24, 0xaf, 0xff, 0xff, 0xf5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0xff, 0xfd, 0x20, 0x0, + 0x0, 0x2, 0xdf, 0xff, 0xff, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7f, 0xfe, 0x30, 0x1, + 0x41, 0x0, 0x1d, 0xff, 0xff, 0xe1, 0x0, 0x0, + 0x0, 0x0, 0x9c, 0x10, 0x4, 0xef, 0xf5, 0x1, + 0xff, 0x80, 0x3, 0xff, 0xff, 0xfc, 0x0, 0x0, + 0x0, 0x4, 0xff, 0xe3, 0x0, 0x2d, 0xff, 0x70, + 0xff, 0xf9, 0x0, 0xcf, 0xff, 0xff, 0x60, 0x0, + 0x0, 0xd, 0xff, 0xff, 0x60, 0x0, 0xaf, 0xfd, + 0xff, 0xff, 0x20, 0x7f, 0xff, 0xff, 0xe0, 0x0, + 0x0, 0x4f, 0xff, 0xff, 0xf3, 0x0, 0x7, 0xff, + 0xff, 0xff, 0x60, 0x5f, 0xff, 0xff, 0xf6, 0x0, + 0x0, 0x6f, 0xff, 0xff, 0xf4, 0x0, 0x0, 0x4e, + 0xff, 0xff, 0x70, 0x4f, 0xff, 0xff, 0xf6, 0x0, + 0x0, 0xf, 0xff, 0xff, 0xf6, 0x0, 0x0, 0x2, + 0xcf, 0xff, 0x40, 0x6f, 0xff, 0xff, 0xe0, 0x0, + 0x0, 0x7, 0xff, 0xff, 0xfb, 0x0, 0x0, 0x0, + 0xa, 0xff, 0xb1, 0xbf, 0xff, 0xff, 0x60, 0x0, + 0x0, 0x0, 0xdf, 0xff, 0xff, 0x20, 0x0, 0x0, + 0x0, 0x7f, 0xfe, 0xff, 0xff, 0xfc, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0xff, 0xff, 0xd0, 0x0, 0x0, + 0x0, 0x4, 0xef, 0xff, 0xff, 0xf2, 0x0, 0x0, + 0x0, 0x0, 0x5, 0xff, 0xff, 0xfc, 0x20, 0x0, + 0x0, 0x0, 0x1c, 0xff, 0xff, 0x50, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5f, 0xff, 0xff, 0xf9, 0x42, + 0x24, 0x60, 0x0, 0x9f, 0xfe, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xef, 0xff, 0xff, 0xff, + 0xff, 0xfb, 0x10, 0x6, 0xff, 0xe4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x2b, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe3, 0x0, 0x3e, 0xff, 0x70, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4c, 0xff, 0xff, + 0xff, 0xff, 0xc5, 0x0, 0x1, 0xcf, 0xfb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x26, 0x8a, + 0x98, 0x52, 0x0, 0x0, 0x0, 0x9, 0xff, 0xc0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xd0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, + + /* U+F071 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xff, 0x70, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, + 0xff, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xaf, 0xff, 0xfb, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xff, 0xff, + 0xff, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7f, 0xff, 0xee, 0xff, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, + 0xff, 0x11, 0xff, 0xff, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xff, 0xfe, 0x0, 0xef, + 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3f, 0xff, 0xfe, 0x0, 0xef, 0xff, 0xf3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xcf, 0xff, 0xfe, + 0x0, 0xef, 0xff, 0xfd, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xff, 0xff, 0xfe, 0x0, 0xef, 0xff, + 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, 0x1e, 0xff, + 0xff, 0xfe, 0x0, 0xef, 0xff, 0xff, 0xe1, 0x0, + 0x0, 0x0, 0x0, 0x9f, 0xff, 0xff, 0xff, 0x11, + 0xff, 0xff, 0xff, 0xf9, 0x0, 0x0, 0x0, 0x2, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x30, 0x0, 0x0, 0xc, 0xff, 0xff, 0xff, + 0xff, 0xdd, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0, + 0x0, 0x5f, 0xff, 0xff, 0xff, 0xfb, 0x0, 0xbf, + 0xff, 0xff, 0xff, 0xf5, 0x0, 0x0, 0xef, 0xff, + 0xff, 0xff, 0xf9, 0x0, 0x9f, 0xff, 0xff, 0xff, + 0xfe, 0x0, 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x66, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe0, 0xd, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xd0, 0x2, 0x9b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x20, + + /* U+F074 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xff, 0xfd, 0x10, 0x4, 0x44, 0x42, 0x0, + 0x0, 0x0, 0x0, 0x2, 0x44, 0xff, 0xff, 0xd1, + 0xcf, 0xff, 0xff, 0xc2, 0x0, 0x0, 0x2, 0xcf, + 0xff, 0xff, 0xff, 0xfc, 0xef, 0xff, 0xff, 0xfe, + 0x20, 0x0, 0x2e, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x4b, 0xbb, 0xbf, 0xff, 0xd0, 0x0, 0xdf, 0xff, + 0xbb, 0xff, 0xff, 0xf5, 0x0, 0x0, 0x3, 0xff, + 0xf9, 0x6, 0xff, 0xf3, 0x0, 0xff, 0xff, 0x60, + 0x0, 0x0, 0x0, 0x6f, 0xff, 0x50, 0xcf, 0x60, + 0x0, 0xef, 0xf6, 0x0, 0x0, 0x0, 0x0, 0xa, + 0xff, 0xf2, 0x19, 0x0, 0x0, 0x4a, 0x50, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xdf, 0xfc, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3f, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0x6, 0xff, 0xf5, 0x0, + 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2f, + 0x70, 0xaf, 0xff, 0x20, 0x0, 0xbf, 0xd1, 0x0, + 0x0, 0x0, 0x0, 0xcf, 0xf3, 0xd, 0xff, 0xc0, + 0x0, 0xff, 0xfd, 0x10, 0x4, 0x44, 0x4b, 0xff, + 0xf3, 0x3, 0xff, 0xfb, 0x44, 0xff, 0xff, 0xd1, + 0xcf, 0xff, 0xff, 0xff, 0x60, 0x0, 0x6f, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0xef, 0xff, 0xff, 0xf8, + 0x0, 0x0, 0x8, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x4b, 0xbb, 0xb9, 0x30, 0x0, 0x0, 0x0, 0x39, + 0xbb, 0xff, 0xff, 0xf5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xef, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4a, 0x40, 0x0, + + /* U+F077 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, + 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xcf, 0xff, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1c, 0xff, 0xff, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xcf, + 0xff, 0x7c, 0xff, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1c, 0xff, 0xf6, 0x0, 0xcf, 0xff, 0x60, + 0x0, 0x0, 0x0, 0x1, 0xcf, 0xff, 0x60, 0x0, + 0xc, 0xff, 0xf6, 0x0, 0x0, 0x0, 0x1c, 0xff, + 0xf6, 0x0, 0x0, 0x0, 0xcf, 0xff, 0x60, 0x0, + 0x1, 0xcf, 0xff, 0x60, 0x0, 0x0, 0x0, 0xc, + 0xff, 0xf6, 0x0, 0x1c, 0xff, 0xf6, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xcf, 0xff, 0x60, 0x9f, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xff, + 0xf2, 0x9f, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xcf, 0xf2, 0x6, 0x40, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x40, + + /* U+F078 "" */ + 0x6, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0x40, 0x9f, 0xf6, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1, 0xcf, 0xf2, 0x9f, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xff, + 0xf2, 0x1c, 0xff, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x1, 0xcf, 0xff, 0x70, 0x1, 0xcf, 0xff, 0x60, + 0x0, 0x0, 0x0, 0xc, 0xff, 0xf7, 0x0, 0x0, + 0x1c, 0xff, 0xf6, 0x0, 0x0, 0x0, 0xcf, 0xff, + 0x70, 0x0, 0x0, 0x1, 0xcf, 0xff, 0x60, 0x0, + 0xc, 0xff, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x1c, + 0xff, 0xf6, 0x0, 0xcf, 0xff, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x1, 0xcf, 0xff, 0x7c, 0xff, 0xf7, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xff, + 0xff, 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0xcf, 0xff, 0xf7, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xff, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x64, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F079 "" */ + 0x0, 0x0, 0x6b, 0x60, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7f, 0xff, 0x60, 0x0, 0x0, 0x1, 0x44, 0x44, + 0x44, 0x20, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff, + 0xff, 0x60, 0x0, 0x1, 0xff, 0xff, 0xff, 0xff, + 0xc2, 0x0, 0x0, 0x0, 0x6f, 0xff, 0xff, 0xff, + 0x60, 0x0, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xe2, + 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, 0xfe, 0x0, + 0x0, 0x7b, 0xbb, 0xbb, 0xbf, 0xff, 0xa0, 0x0, + 0x0, 0xaf, 0xff, 0xff, 0xff, 0xb0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3f, 0xfe, 0x0, 0x0, 0x0, + 0x23, 0xff, 0xf3, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, 0x0, 0xf, + 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0x0, + 0x0, 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0xbc, 0xff, 0xfc, 0xb4, 0x0, 0x0, 0xc, 0xff, + 0xb4, 0x44, 0x44, 0x41, 0x0, 0x0, 0xef, 0xff, + 0xff, 0xff, 0xe0, 0x0, 0x0, 0x5f, 0xff, 0xff, + 0xff, 0xff, 0xf1, 0x0, 0xb, 0xff, 0xff, 0xff, + 0xfb, 0x0, 0x0, 0x0, 0x8f, 0xff, 0xff, 0xff, + 0xff, 0x20, 0x0, 0x1c, 0xff, 0xff, 0xfc, 0x10, + 0x0, 0x0, 0x0, 0x39, 0xbb, 0xbb, 0xbb, 0x70, + 0x0, 0x0, 0x1c, 0xff, 0xfc, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1c, 0xfc, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0x0, 0x0, 0x0, + + /* U+F07B "" */ + 0x0, 0x24, 0x44, 0x44, 0x41, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1c, 0xff, 0xff, 0xff, + 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xaf, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xb6, 0x44, 0x44, 0x44, 0x42, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf5, 0x3, 0x9b, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x30, + + /* U+F093 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3d, 0xd3, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3, 0xff, 0xff, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x3f, 0xff, 0xff, 0xf3, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xff, 0xff, 0xff, 0xff, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3f, 0xff, 0xff, 0xff, 0xff, + 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xff, + 0xfe, 0xaf, 0xfa, 0xef, 0xff, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x2f, 0xff, 0xe3, 0x8f, 0xf8, 0x3e, + 0xff, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xfe, + 0x30, 0x8f, 0xf8, 0x3, 0xff, 0xf7, 0x0, 0x0, + 0x0, 0x0, 0x2d, 0xd3, 0x0, 0x8f, 0xf8, 0x0, + 0x3d, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xf8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xf8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xf8, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x68, 0x88, 0x88, 0x80, 0x7f, 0xf7, 0x8, + 0x88, 0x88, 0x86, 0x10, 0x3e, 0xff, 0xff, 0xff, + 0xf3, 0x2d, 0xd2, 0x3f, 0xff, 0xff, 0xff, 0xe3, + 0xcf, 0xff, 0xff, 0xff, 0xfc, 0x10, 0x1, 0xcf, + 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe9, 0x9e, 0xff, 0xff, 0xf9, 0x4e, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf4, 0xc, 0xff, 0xef, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xcf, 0xfe, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf8, 0x8, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x80, + + /* U+F095 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x6a, 0xee, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x4d, 0xff, 0xff, 0xfd, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, 0xff, + 0xff, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xb0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, + 0xff, 0xff, 0xff, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xdf, 0xff, 0xff, 0xff, 0xf8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, + 0xff, 0xff, 0xff, 0xff, 0xb0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff, 0xff, 0xff, + 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xff, 0xff, 0xff, 0xf4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, 0xff, + 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x9f, 0xff, 0xff, 0x30, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xff, + 0xff, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xb, 0xff, 0xff, 0xf7, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3f, 0xff, 0xff, 0xf4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, 0xff, + 0xf4, 0x0, 0x0, 0x4, 0xb8, 0x20, 0x0, 0x0, + 0x0, 0x0, 0xdf, 0xff, 0xff, 0xf7, 0x0, 0x4, + 0xff, 0xff, 0xb4, 0x0, 0x0, 0x0, 0x2, 0xef, + 0xff, 0xff, 0xfc, 0x32, 0xff, 0xff, 0xff, 0xfd, + 0x40, 0x0, 0x0, 0x3, 0xff, 0xff, 0xff, 0xff, + 0xef, 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, + 0x3, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe0, 0x0, 0x0, 0x0, 0x2, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x9e, 0xff, + 0xff, 0xff, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0x7a, 0xde, 0xfe, 0x40, + 0x0, + + /* U+F0C4 "" */ + 0x0, 0x3b, 0xef, 0xc5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6, 0xff, 0xff, 0xff, + 0xa0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x87, 0x10, + 0x3f, 0xff, 0xff, 0xff, 0xf7, 0x0, 0x0, 0x0, + 0x0, 0xaf, 0xff, 0xf3, 0xaf, 0xfc, 0x21, 0x9f, + 0xfe, 0x0, 0x0, 0x0, 0xa, 0xff, 0xff, 0xf3, + 0xef, 0xf3, 0x0, 0xe, 0xff, 0x20, 0x0, 0x0, + 0xaf, 0xff, 0xff, 0x40, 0xff, 0xf0, 0x0, 0xc, + 0xff, 0x40, 0x0, 0x9, 0xff, 0xff, 0xf4, 0x0, + 0xdf, 0xf5, 0x0, 0x1f, 0xff, 0x20, 0x0, 0x9f, + 0xff, 0xff, 0x50, 0x0, 0x8f, 0xfe, 0x75, 0xdf, + 0xff, 0x20, 0x8, 0xff, 0xff, 0xf5, 0x0, 0x0, + 0x1e, 0xff, 0xff, 0xff, 0xff, 0xe2, 0x8f, 0xff, + 0xff, 0x50, 0x0, 0x0, 0x3, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf5, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xaa, 0x8d, 0xff, 0xff, 0xff, 0xff, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xdf, 0xff, 0xff, 0xf5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x33, 0x17, + 0xff, 0xff, 0xf5, 0x5, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0x50, 0x6f, + 0xe2, 0x0, 0x0, 0x0, 0xb, 0xff, 0xff, 0xff, + 0xff, 0xf5, 0x6, 0xff, 0xfe, 0x30, 0x0, 0x0, + 0x6f, 0xff, 0xdc, 0xff, 0xff, 0x50, 0xc, 0xff, + 0xff, 0xe3, 0x0, 0x0, 0xcf, 0xf9, 0x0, 0x4f, + 0xff, 0x10, 0x0, 0xcf, 0xff, 0xff, 0x30, 0x0, + 0xff, 0xf1, 0x0, 0xc, 0xff, 0x40, 0x0, 0xc, + 0xff, 0xff, 0xf3, 0x0, 0xef, 0xf2, 0x0, 0xd, + 0xff, 0x30, 0x0, 0x0, 0xbf, 0xff, 0xff, 0x40, + 0xbf, 0xfc, 0x21, 0x9f, 0xff, 0x0, 0x0, 0x0, + 0xb, 0xff, 0xff, 0xf3, 0x4f, 0xff, 0xff, 0xff, + 0xf7, 0x0, 0x0, 0x0, 0x0, 0xaf, 0xff, 0xf3, + 0x6, 0xff, 0xff, 0xff, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x4, 0x87, 0x10, 0x0, 0x4b, 0xef, 0xc6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F0C5 "" */ + 0x0, 0x0, 0x0, 0x0, 0x3c, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0x80, 0x0, 0x0, 0x0, 0x1, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x0, 0x0, 0x0, 0x6, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x0, 0x0, 0x0, 0x7, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x7, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x7, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x7, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x1, 0x67, 0x77, 0x7, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x3e, 0xff, 0xff, 0x7, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0x7, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf7, 0x77, 0x7, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x7, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x0, 0x7, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x7, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0x0, 0x4, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0xff, 0xf0, 0x0, 0x0, + 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, + 0xff, 0xf0, 0x0, 0x0, 0x4, 0x77, 0x77, 0x77, + 0x77, 0x77, 0x76, 0x10, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff, + 0x70, 0x0, 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xff, 0x70, 0x0, 0x0, 0x0, + 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff, + 0x70, 0x0, 0x0, 0x0, 0xef, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x60, 0x0, 0x0, 0x0, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x10, 0x0, 0x0, 0x0, 0x8, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc3, 0x0, 0x0, 0x0, 0x0, + + /* U+F0C7 "" */ + 0x0, 0x24, 0x44, 0x44, 0x44, 0x44, 0x44, 0x30, + 0x0, 0x0, 0x1, 0xcf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf5, 0x0, 0x0, 0xaf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x0, 0xf, + 0xff, 0xfb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0xff, + 0xf6, 0x0, 0xff, 0xf3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3f, 0xff, 0xf6, 0xf, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xf4, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, + 0xff, 0xdf, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, + 0xb4, 0x44, 0x44, 0x44, 0x44, 0x4b, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0xce, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf9, 0x0, 0x9, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x0, + 0x0, 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x90, 0x0, 0x0, 0x9f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfa, 0x0, 0x0, 0xa, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x0, + 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf8, 0x58, 0xff, 0xff, 0xff, 0xff, 0xfd, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x50, 0x39, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x30, + + /* U+F0C9 "" */ + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x40, 0xcf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xce, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0x4b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf8, + + /* U+F0E0 "" */ + 0x3c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc3, 0xcf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x8f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x70, 0x50, 0x4e, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, 0x5, + 0xfa, 0x1, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfb, 0x10, 0xaf, 0xff, 0xd2, 0x8, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x2d, 0xff, + 0xff, 0xff, 0x60, 0x4e, 0xff, 0xff, 0xff, 0xff, + 0xe4, 0x6, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x1, + 0xbf, 0xff, 0xff, 0xfb, 0x10, 0xaf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xd2, 0x8, 0xff, 0xff, 0x80, + 0x2d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x60, 0x4d, 0xd4, 0x6, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfa, 0x0, 0x0, 0xaf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe9, 0x9e, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf8, 0x8, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x80, + + /* U+F0E7 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, + 0xdd, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4, 0xff, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xff, 0xff, 0x30, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x8, 0xff, 0xff, 0xc0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xff, 0xff, 0xf5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1c, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0xff, 0xff, + 0xff, 0x70, 0x0, 0x0, 0x0, 0x0, 0x3e, 0xff, + 0xff, 0xff, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x4f, + 0xff, 0xff, 0xff, 0xfa, 0x0, 0x0, 0x0, 0x0, + 0x6f, 0xff, 0xff, 0xff, 0xff, 0x30, 0x0, 0x0, + 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x77, + 0x77, 0x50, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x55, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf5, 0x5, 0x77, 0x77, + 0x7e, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, 0x0, + 0x0, 0x2, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x0, + 0x0, 0x0, 0x0, 0x9f, 0xff, 0xff, 0xff, 0xf4, + 0x0, 0x0, 0x0, 0x0, 0x1f, 0xff, 0xff, 0xff, + 0xe3, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff, 0xff, + 0xff, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x0, 0xef, + 0xff, 0xff, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5f, 0xff, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xc, 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xff, 0xff, 0x60, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff, 0x40, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0xdd, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F0EA "" */ + 0x0, 0x0, 0x2, 0xcf, 0xc2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0x44, 0x4e, 0xff, + 0xfe, 0x44, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6f, 0xff, 0xff, 0xb3, 0xbf, 0xff, 0xff, 0x60, + 0x0, 0x0, 0x0, 0x0, 0xef, 0xff, 0xff, 0x80, + 0x8f, 0xff, 0xff, 0xe0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xcb, 0xb0, + 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xf9, 0x8, 0xff, 0xff, + 0xff, 0x5, 0x10, 0x0, 0xff, 0xff, 0xff, 0xff, + 0xf2, 0x4f, 0xff, 0xff, 0xff, 0x7, 0xd1, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, + 0xff, 0x7, 0xfd, 0x10, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x7f, 0xff, 0xff, 0xff, 0x7, 0xff, 0xd1, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, + 0xff, 0x3, 0x77, 0x75, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x7f, 0xff, 0xff, 0xff, 0x70, 0x0, 0x0, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, + 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x3c, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfc, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, + + /* U+F0F3 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x27, 0xff, 0xf7, 0x10, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xff, + 0xff, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xaf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x3f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 0x0, + 0x0, 0x0, 0xa, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf9, 0x0, 0x0, 0x0, 0x0, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, 0x0, 0x0, + 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x10, 0x0, 0x0, 0x3, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf3, 0x0, 0x0, 0x0, 0x8f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, + 0x0, 0x0, 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0x0, 0x0, 0x7, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0x0, + 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf3, 0x0, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, 0xd, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0x0, 0x17, 0x77, 0x77, 0x77, 0x77, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0xff, 0xff, + 0xf6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1e, 0xff, 0xfe, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0xfc, 0x30, + 0x0, 0x0, 0x0, 0x0, + + /* U+F11C "" */ + 0x8, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe8, 0x8, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf8, 0xef, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xef, 0xff, 0x20, 0x2f, 0xa0, 0xa, 0xf2, 0x2, + 0xfa, 0x0, 0xaf, 0x20, 0x2f, 0xff, 0xff, 0xf0, + 0x0, 0xf7, 0x0, 0x7f, 0x0, 0xf, 0x70, 0x7, + 0xf0, 0x0, 0xff, 0xff, 0xff, 0x20, 0x2f, 0xa0, + 0xa, 0xf2, 0x2, 0xfa, 0x0, 0xaf, 0x20, 0x2f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xa7, 0xaf, 0xe8, 0x8e, 0xfa, 0x7a, 0xfe, 0x88, + 0xef, 0xa7, 0xaf, 0xff, 0xff, 0xf0, 0x0, 0xf8, + 0x0, 0x8f, 0x0, 0xf, 0x80, 0x8, 0xf0, 0x0, + 0xff, 0xff, 0xff, 0x0, 0xf, 0x80, 0x8, 0xf0, + 0x0, 0xf8, 0x0, 0x8f, 0x0, 0xf, 0xff, 0xff, + 0xfa, 0x7a, 0xfe, 0x88, 0xef, 0xa7, 0xaf, 0xe8, + 0x8e, 0xfa, 0x7a, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf2, 0x2, 0xfa, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xa, 0xf2, 0x2, 0xff, 0xff, + 0xff, 0x0, 0xf, 0x70, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7f, 0x0, 0xf, 0xff, 0xff, 0xf2, 0x2, + 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xf2, + 0x2, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x8e, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x80, + + /* U+F124 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x5, 0xa7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2, 0x8e, 0xff, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5b, 0xff, 0xff, 0xff, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x18, 0xef, 0xff, 0xff, + 0xff, 0xa0, 0x0, 0x0, 0x0, 0x4, 0xbf, 0xff, + 0xff, 0xff, 0xff, 0xf4, 0x0, 0x0, 0x1, 0x7d, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x0, 0x0, + 0x3a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x70, 0x0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf1, 0x0, 0x3f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf9, 0x0, 0x0, 0xbf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff, + 0xff, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7, 0xff, 0xff, 0xf6, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x7f, 0xff, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff, 0xff, + 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x7f, 0xff, 0xf2, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x7, 0xff, 0xfc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, + 0xff, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6f, 0xf8, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0, + 0x0, 0x0, + + /* U+F158 "" */ + 0x0, 0x8, 0xff, 0xff, 0xff, 0xff, 0xd9, 0x20, + 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf7, 0x0, 0x0, 0xf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x60, 0x0, 0xf, 0xff, 0x11, 0x11, + 0x11, 0x4c, 0xff, 0xf1, 0x0, 0xf, 0xff, 0x0, + 0x0, 0x0, 0x0, 0xdf, 0xf8, 0x0, 0xf, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x5f, 0xfc, 0x0, 0xf, + 0xff, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xff, 0x0, + 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xff, + 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, 0x4f, + 0xfd, 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, + 0xdf, 0xf8, 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, + 0x3c, 0xff, 0xf2, 0x8f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x70, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf8, 0x0, 0x9f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfb, 0x30, 0x0, 0x0, 0x1f, + 0xff, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x1f, 0xff, 0x11, 0x11, 0x11, 0x10, 0x0, 0x0, + 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x80, 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xf8, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F1EB "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0x44, + 0x31, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x48, 0xcf, 0xff, 0xff, 0xff, + 0xfc, 0x84, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x8e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe8, 0x10, 0x0, 0x0, 0x0, 0x0, 0x8f, + 0xff, 0xff, 0xff, 0xec, 0xbb, 0xce, 0xff, 0xff, + 0xff, 0xf8, 0x0, 0x0, 0x0, 0x3e, 0xff, 0xff, + 0xe8, 0x40, 0x0, 0x0, 0x0, 0x4, 0x8e, 0xff, + 0xff, 0xe3, 0x0, 0x7, 0xff, 0xff, 0xd5, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, 0xff, + 0xff, 0x70, 0x8f, 0xff, 0xe5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5e, 0xff, + 0xf8, 0xff, 0xfc, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xcf, 0xff, + 0x7e, 0x80, 0x0, 0x0, 0x0, 0x37, 0xcd, 0xff, + 0xdb, 0x73, 0x0, 0x0, 0x0, 0x8, 0xe7, 0x0, + 0x0, 0x0, 0x0, 0x4c, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xc4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0xdf, 0xff, 0xfa, 0x52, 0x0, 0x25, 0xaf, 0xff, + 0xfd, 0x10, 0x0, 0x0, 0x0, 0x0, 0x6, 0xff, + 0xf9, 0x10, 0x0, 0x0, 0x0, 0x1, 0xaf, 0xff, + 0x60, 0x0, 0x0, 0x0, 0x0, 0x1, 0xde, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0xee, 0x10, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c, 0xff, + 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0xff, 0xfa, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xef, 0xff, 0xfe, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xdf, 0xff, 0xfd, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5f, 0xff, 0xf5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x99, 0x30, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, + + /* U+F240 "" */ + 0x0, 0x3, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x10, 0x0, 0x0, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb1, 0x0, 0x6f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, + 0xc, 0xff, 0xdb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xcf, 0xff, 0x10, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xf4, 0xf, 0xff, 0x8, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb, 0xff, + 0xf5, 0xff, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0xbf, 0xff, 0xcf, 0xff, + 0x8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb, 0xff, 0xfc, 0xff, 0xf0, 0x8f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xbf, + 0xff, 0xcf, 0xff, 0x8, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xb, 0xff, 0xfc, 0xff, + 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf0, 0xbf, 0xff, 0x5f, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0xff, 0x40, 0xef, 0xf6, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x45, 0xef, 0xf2, 0xa, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0x0, 0x1e, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x40, 0x0, 0x7, 0xab, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x20, 0x0, + + /* U+F241 "" */ + 0x0, 0x3, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x10, 0x0, 0x0, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb1, 0x0, 0x6f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, + 0xc, 0xff, 0xdb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xcf, 0xff, 0x10, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xf4, 0xf, 0xff, 0xb, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf4, 0x0, 0x0, 0xb, 0xff, + 0xf5, 0xff, 0xf0, 0xbf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x40, 0x0, 0x0, 0xbf, 0xff, 0xcf, 0xff, + 0xb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x0, + 0x0, 0xb, 0xff, 0xfc, 0xff, 0xf0, 0xbf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0xbf, + 0xff, 0xcf, 0xff, 0xb, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf4, 0x0, 0x0, 0xb, 0xff, 0xfc, 0xff, + 0xf0, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, + 0x0, 0x0, 0xbf, 0xff, 0x5f, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0xff, 0x40, 0xef, 0xf6, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x45, 0xef, 0xf2, 0xa, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0x0, 0x1e, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x40, 0x0, 0x7, 0xab, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x20, 0x0, + + /* U+F242 "" */ + 0x0, 0x3, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x10, 0x0, 0x0, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb1, 0x0, 0x6f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, + 0xc, 0xff, 0xdb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xcf, 0xff, 0x10, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xf4, 0xf, 0xff, 0xb, 0xff, 0xff, + 0xff, 0xff, 0x40, 0x0, 0x0, 0x0, 0xb, 0xff, + 0xf5, 0xff, 0xf0, 0xbf, 0xff, 0xff, 0xff, 0xf4, + 0x0, 0x0, 0x0, 0x0, 0xbf, 0xff, 0xcf, 0xff, + 0xb, 0xff, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, + 0x0, 0xb, 0xff, 0xfc, 0xff, 0xf0, 0xbf, 0xff, + 0xff, 0xff, 0xf4, 0x0, 0x0, 0x0, 0x0, 0xbf, + 0xff, 0xcf, 0xff, 0xb, 0xff, 0xff, 0xff, 0xff, + 0x40, 0x0, 0x0, 0x0, 0xb, 0xff, 0xfc, 0xff, + 0xf0, 0xbf, 0xff, 0xff, 0xff, 0xf4, 0x0, 0x0, + 0x0, 0x0, 0xbf, 0xff, 0x5f, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0xff, 0x40, 0xef, 0xf6, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x45, 0xef, 0xf2, 0xa, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0x0, 0x1e, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x40, 0x0, 0x7, 0xab, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x20, 0x0, + + /* U+F243 "" */ + 0x0, 0x3, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x10, 0x0, 0x0, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb1, 0x0, 0x6f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, + 0xc, 0xff, 0xdb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xcf, 0xff, 0x10, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xf4, 0xf, 0xff, 0x8, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xff, + 0xf5, 0xff, 0xf0, 0x8f, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xbf, 0xff, 0xcf, 0xff, + 0x8, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xff, 0xfc, 0xff, 0xf0, 0x8f, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, + 0xff, 0xcf, 0xff, 0x8, 0xff, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb, 0xff, 0xfc, 0xff, + 0xf0, 0x8f, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbf, 0xff, 0x5f, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0xff, 0x40, 0xef, 0xf6, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x45, 0xef, 0xf2, 0xa, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0x0, 0x1e, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x40, 0x0, 0x7, 0xab, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x20, 0x0, + + /* U+F244 "" */ + 0x0, 0x3, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x10, 0x0, 0x0, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb1, 0x0, 0x6f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, + 0xc, 0xff, 0xdb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xcf, 0xff, 0x10, 0xff, 0xf0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xcf, 0xf4, 0xf, 0xff, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xff, + 0xf5, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xbf, 0xff, 0xcf, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xb, 0xff, 0xfc, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, + 0xff, 0xcf, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0xb, 0xff, 0xfc, 0xff, + 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xbf, 0xff, 0x5f, 0xff, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, + 0xff, 0x40, 0xef, 0xf6, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x45, 0xef, 0xf2, 0xa, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0x0, 0x1e, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x40, 0x0, 0x7, 0xab, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb9, 0x20, 0x0, + + /* U+F287 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, + 0xff, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x77, 0xff, + 0xff, 0xa0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x7, 0xff, 0xff, 0xff, + 0xfc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3, 0xfc, 0x33, 0xdf, 0xff, + 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xbf, 0x20, 0x2, 0xac, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, + 0x0, 0x0, 0x2f, 0xa0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0xff, 0xd3, + 0x0, 0xa, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1a, 0x20, 0x0, 0xb, 0xff, 0xff, 0xe0, + 0x3, 0xfa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x2, 0xff, 0x80, 0x1, 0xff, 0xff, 0xff, 0xcb, + 0xff, 0xdb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xcf, 0xff, 0xd4, 0x2f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x70, 0xdf, 0xff, 0xff, 0x10, 0x0, + 0x2, 0xee, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, + 0xfc, 0x20, 0x3, 0xef, 0xff, 0x60, 0x0, 0x0, + 0x5, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x2, 0xe5, + 0x0, 0x0, 0x1, 0x56, 0x20, 0x0, 0x0, 0x0, + 0xd, 0xe0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x6f, 0x80, 0xb, 0xff, 0xff, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xdf, 0x74, 0xef, 0xff, 0xf2, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0xef, 0xff, 0xff, 0xff, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x56, 0xef, 0xff, 0xf2, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xc, 0xff, 0xff, 0x20, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1, 0x11, 0x0, 0x0, 0x0, 0x0, + + /* U+F293 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x28, 0xce, 0xff, 0xeb, + 0x60, 0x0, 0x0, 0x0, 0x0, 0xaf, 0xff, 0xff, + 0xff, 0xff, 0xe3, 0x0, 0x0, 0x0, 0xcf, 0xff, + 0xff, 0x5f, 0xff, 0xff, 0xf4, 0x0, 0x0, 0x9f, + 0xff, 0xff, 0xf0, 0x5f, 0xff, 0xff, 0xe1, 0x0, + 0x2f, 0xff, 0xff, 0xff, 0x0, 0x6f, 0xff, 0xff, + 0x80, 0x8, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x6f, + 0xff, 0xfe, 0x0, 0xdf, 0xff, 0xcf, 0xff, 0x1, + 0x60, 0x7f, 0xff, 0xf2, 0x1f, 0xff, 0x80, 0x9f, + 0xf0, 0x1f, 0x60, 0x7f, 0xff, 0x54, 0xff, 0xfc, + 0x10, 0x9f, 0x1, 0xf7, 0x6, 0xff, 0xf7, 0x6f, + 0xff, 0xfc, 0x10, 0x70, 0x17, 0x5, 0xff, 0xff, + 0x97, 0xff, 0xff, 0xfc, 0x10, 0x0, 0x3, 0xff, + 0xff, 0xfa, 0x7f, 0xff, 0xff, 0xfc, 0x10, 0x2, + 0xef, 0xff, 0xff, 0xb7, 0xff, 0xff, 0xff, 0xf3, + 0x0, 0x5f, 0xff, 0xff, 0xfb, 0x7f, 0xff, 0xff, + 0xf4, 0x0, 0x0, 0x6f, 0xff, 0xff, 0xa6, 0xff, + 0xff, 0xf4, 0x3, 0x2, 0x10, 0x7f, 0xff, 0xfa, + 0x4f, 0xff, 0xf4, 0x4, 0xe0, 0x4e, 0x20, 0x8f, + 0xff, 0x82, 0xff, 0xf7, 0x4, 0xff, 0x4, 0xfa, + 0x2, 0xff, 0xf6, 0xe, 0xff, 0xf7, 0xff, 0xf0, + 0x59, 0x2, 0xef, 0xff, 0x30, 0xaf, 0xff, 0xff, + 0xff, 0x0, 0x2, 0xef, 0xff, 0xe0, 0x3, 0xff, + 0xff, 0xff, 0xf0, 0x2, 0xef, 0xff, 0xf9, 0x0, + 0xb, 0xff, 0xff, 0xff, 0x2, 0xef, 0xff, 0xff, + 0x20, 0x0, 0x1d, 0xff, 0xff, 0xf3, 0xef, 0xff, + 0xff, 0x70, 0x0, 0x0, 0x1b, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x70, 0x0, 0x0, 0x0, 0x3, 0x9c, + 0xff, 0xfe, 0xc7, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + + /* U+F2ED "" */ + 0x0, 0x0, 0x0, 0x3b, 0xcc, 0xcc, 0xcb, 0x30, + 0x0, 0x0, 0x0, 0x44, 0x44, 0x4d, 0xff, 0xff, + 0xff, 0xfd, 0x44, 0x44, 0x40, 0xcf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xce, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x4b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf8, 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x80, 0x8, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0, 0x8f, + 0xff, 0x66, 0xff, 0xd1, 0xdf, 0xf6, 0x6f, 0xff, + 0x80, 0x8, 0xff, 0xf4, 0x4f, 0xfc, 0xc, 0xff, + 0x44, 0xff, 0xf8, 0x0, 0x8f, 0xff, 0x44, 0xff, + 0xc0, 0xcf, 0xf4, 0x4f, 0xff, 0x80, 0x8, 0xff, + 0xf4, 0x4f, 0xfc, 0xc, 0xff, 0x44, 0xff, 0xf8, + 0x0, 0x8f, 0xff, 0x44, 0xff, 0xc0, 0xcf, 0xf4, + 0x4f, 0xff, 0x80, 0x8, 0xff, 0xf4, 0x4f, 0xfc, + 0xc, 0xff, 0x44, 0xff, 0xf8, 0x0, 0x8f, 0xff, + 0x44, 0xff, 0xc0, 0xcf, 0xf4, 0x4f, 0xff, 0x80, + 0x8, 0xff, 0xf4, 0x4f, 0xfc, 0xc, 0xff, 0x44, + 0xff, 0xf8, 0x0, 0x8f, 0xff, 0x44, 0xff, 0xc0, + 0xcf, 0xf4, 0x4f, 0xff, 0x80, 0x8, 0xff, 0xf4, + 0x4f, 0xfc, 0xc, 0xff, 0x44, 0xff, 0xf8, 0x0, + 0x8f, 0xff, 0x44, 0xff, 0xc0, 0xcf, 0xf4, 0x4f, + 0xff, 0x80, 0x8, 0xff, 0xf6, 0x6f, 0xfd, 0x1d, + 0xff, 0x66, 0xff, 0xf8, 0x0, 0x6f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x1, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe1, 0x0, 0x3, 0xcf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xc3, 0x0, + + /* U+F304 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6d, 0xe9, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xff, 0xfc, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9f, 0xff, 0xff, 0xfc, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0xff, 0xff, + 0xff, 0xf9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x71, 0x1d, 0xff, 0xff, 0xff, 0xe0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xd1, 0x1d, + 0xff, 0xff, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9f, 0xff, 0xd1, 0x1d, 0xff, 0xff, 0x60, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xff, 0xff, + 0xd1, 0x1d, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9f, 0xff, 0xff, 0xff, 0xd1, 0x1d, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x9f, 0xff, 0xff, + 0xff, 0xff, 0xd1, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0xcf, 0xff, 0xff, 0xff, 0xff, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xff, + 0xff, 0xff, 0xff, 0x90, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x5, 0xff, 0xff, 0xff, 0xff, 0x90, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, + 0xff, 0xff, 0xff, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xe, 0xff, 0xff, 0xc7, 0x20, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xbe, 0xa5, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, + + /* U+F379 "" */ + 0x0, 0x0, 0x0, 0x0, 0x26, 0x9a, 0xa8, 0x51, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, + 0xff, 0xff, 0xff, 0xff, 0xb3, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x90, 0x0, 0x0, 0x0, 0x3, 0xef, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0, 0x0, + 0x0, 0x2e, 0xff, 0xff, 0xff, 0xf8, 0xcf, 0xff, + 0xff, 0xff, 0xb0, 0x0, 0x0, 0xcf, 0xff, 0xff, + 0xff, 0xf0, 0xb6, 0x6f, 0xff, 0xff, 0xf7, 0x0, + 0x6, 0xff, 0xff, 0xff, 0x2, 0x40, 0xc2, 0x7f, + 0xff, 0xff, 0xff, 0x10, 0xd, 0xff, 0xff, 0xff, + 0xa1, 0x0, 0x0, 0x5d, 0xff, 0xff, 0xff, 0x90, + 0x3f, 0xff, 0xff, 0xff, 0xf3, 0x5, 0x82, 0x0, + 0xbf, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xff, + 0xf0, 0xa, 0xff, 0x30, 0x3f, 0xff, 0xff, 0xf3, + 0xaf, 0xff, 0xff, 0xff, 0xb0, 0xd, 0xff, 0x20, + 0x3f, 0xff, 0xff, 0xf5, 0xbf, 0xff, 0xff, 0xff, + 0x70, 0x0, 0x10, 0x0, 0xbf, 0xff, 0xff, 0xf7, + 0xbf, 0xff, 0xff, 0xff, 0x30, 0x6b, 0x60, 0x4, + 0xff, 0xff, 0xff, 0xf7, 0xaf, 0xff, 0xff, 0xff, + 0x0, 0xaf, 0xfc, 0x0, 0x8f, 0xff, 0xff, 0xf5, + 0x7f, 0xff, 0xff, 0x21, 0x0, 0xef, 0xfc, 0x0, + 0x7f, 0xff, 0xff, 0xf2, 0x2f, 0xff, 0xfe, 0x62, + 0x0, 0x3, 0x41, 0x0, 0xbf, 0xff, 0xff, 0xe0, + 0xc, 0xff, 0xff, 0xff, 0x23, 0x30, 0x0, 0x7, + 0xff, 0xff, 0xff, 0x80, 0x5, 0xff, 0xff, 0xfe, + 0xa, 0x63, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x10, + 0x0, 0xbf, 0xff, 0xff, 0xaf, 0x48, 0xff, 0xff, + 0xff, 0xff, 0xf6, 0x0, 0x0, 0x1d, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x0, + 0x0, 0x1, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfa, 0x0, 0x0, 0x0, 0x0, 0xa, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x3b, 0xff, 0xff, 0xff, 0xfe, + 0x91, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0x78, 0x86, 0x30, 0x0, 0x0, 0x0, 0x0, + + /* U+F55A "" */ + 0x0, 0x0, 0x0, 0x2, 0xbf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe8, 0x0, 0x0, 0x0, + 0x3, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf8, 0x0, 0x0, 0x3, 0xef, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe0, 0x0, 0x3, 0xef, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x3, + 0xef, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfe, + 0xff, 0xff, 0xff, 0xf0, 0x3, 0xef, 0xff, 0xff, + 0xff, 0xf9, 0x6, 0xff, 0xf6, 0x9, 0xff, 0xff, + 0xff, 0x3, 0xef, 0xff, 0xff, 0xff, 0xff, 0x80, + 0x6, 0xf6, 0x0, 0x8f, 0xff, 0xff, 0xf3, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x60, 0x2, 0x0, + 0x6f, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x60, 0x0, 0x6f, 0xff, 0xff, + 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf6, 0x0, 0x6, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x0, 0x20, + 0x6, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, + 0xff, 0xff, 0xf8, 0x0, 0x6f, 0x60, 0x8, 0xff, + 0xff, 0xff, 0x0, 0x3e, 0xff, 0xff, 0xff, 0xff, + 0x90, 0x6f, 0xff, 0x60, 0x9f, 0xff, 0xff, 0xf0, + 0x0, 0x3e, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, + 0xff, 0xef, 0xff, 0xff, 0xff, 0x0, 0x0, 0x3e, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf0, 0x0, 0x0, 0x3e, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x0, 0x0, 0x0, 0x3e, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0, 0x0, + 0x0, 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0x80, + + /* U+F7C2 "" */ + 0x0, 0x0, 0x2b, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0x80, 0x0, 0x2, 0xef, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf8, 0x0, 0x2e, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0x2, 0xef, 0xf9, 0x1c, 0xf5, + 0x4f, 0xd1, 0x5f, 0xff, 0x2e, 0xff, 0xf4, 0x8, + 0xf0, 0xe, 0x90, 0xf, 0xff, 0xbf, 0xff, 0xf3, + 0x7, 0xf0, 0xe, 0x90, 0xf, 0xff, 0xff, 0xff, + 0xf5, 0x9, 0xf1, 0xf, 0xa0, 0xf, 0xff, 0xff, + 0xff, 0xfe, 0x9f, 0xfc, 0xbf, 0xf9, 0xcf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x8f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x8, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x80, + + /* U+F8A2 "" */ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xdf, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1d, 0xff, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xdf, 0xff, + 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1d, 0xff, 0xf5, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1, 0xdf, 0xff, 0x50, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x1d, 0xff, 0xf9, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x40, 0xcf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfe, 0x5f, 0xff, 0xfc, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xb4, + 0x6, 0xff, 0xfd, 0x10, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xff, 0xd1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x6, 0xff, 0xfd, 0x10, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0xff, + 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0xff, 0xe0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, + 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 +}; + + +/*--------------------- + * GLYPH DESCRIPTION + *--------------------*/ + +static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { + {.bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */, + {.bitmap_index = 0, .adv_w = 230, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 0, .adv_w = 230, .box_w = 4, .box_h = 15, .ofs_x = 5, .ofs_y = 0}, + {.bitmap_index = 30, .adv_w = 230, .box_w = 9, .box_h = 7, .ofs_x = 3, .ofs_y = 8}, + {.bitmap_index = 62, .adv_w = 230, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 160, .adv_w = 230, .box_w = 11, .box_h = 20, .ofs_x = 2, .ofs_y = -3}, + {.bitmap_index = 270, .adv_w = 230, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 368, .adv_w = 230, .box_w = 12, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 458, .adv_w = 230, .box_w = 4, .box_h = 7, .ofs_x = 5, .ofs_y = 8}, + {.bitmap_index = 472, .adv_w = 230, .box_w = 8, .box_h = 21, .ofs_x = 3, .ofs_y = -4}, + {.bitmap_index = 556, .adv_w = 230, .box_w = 7, .box_h = 21, .ofs_x = 4, .ofs_y = -5}, + {.bitmap_index = 630, .adv_w = 230, .box_w = 13, .box_h = 12, .ofs_x = 1, .ofs_y = 2}, + {.bitmap_index = 708, .adv_w = 230, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 2}, + {.bitmap_index = 769, .adv_w = 230, .box_w = 5, .box_h = 7, .ofs_x = 4, .ofs_y = -3}, + {.bitmap_index = 787, .adv_w = 230, .box_w = 11, .box_h = 2, .ofs_x = 2, .ofs_y = 6}, + {.bitmap_index = 798, .adv_w = 230, .box_w = 4, .box_h = 4, .ofs_x = 5, .ofs_y = 0}, + {.bitmap_index = 806, .adv_w = 230, .box_w = 11, .box_h = 21, .ofs_x = 2, .ofs_y = -4}, + {.bitmap_index = 922, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 999, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1076, .adv_w = 230, .box_w = 10, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1146, .adv_w = 230, .box_w = 10, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1216, .adv_w = 230, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 1300, .adv_w = 230, .box_w = 10, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1370, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1447, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1524, .adv_w = 230, .box_w = 10, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1594, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 1671, .adv_w = 230, .box_w = 4, .box_h = 11, .ofs_x = 5, .ofs_y = 0}, + {.bitmap_index = 1693, .adv_w = 230, .box_w = 6, .box_h = 14, .ofs_x = 4, .ofs_y = -3}, + {.bitmap_index = 1735, .adv_w = 230, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 1801, .adv_w = 230, .box_w = 11, .box_h = 6, .ofs_x = 2, .ofs_y = 4}, + {.bitmap_index = 1834, .adv_w = 230, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 1}, + {.bitmap_index = 1895, .adv_w = 230, .box_w = 9, .box_h = 15, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 1963, .adv_w = 230, .box_w = 14, .box_h = 16, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 2075, .adv_w = 230, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2166, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 2243, .adv_w = 230, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2327, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 2404, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 2481, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 2558, .adv_w = 230, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 2642, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 2719, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 2796, .adv_w = 230, .box_w = 10, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 2866, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 2943, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 3020, .adv_w = 230, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3104, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 3181, .adv_w = 230, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3272, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 3349, .adv_w = 230, .box_w = 13, .box_h = 16, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 3453, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 3530, .adv_w = 230, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3614, .adv_w = 230, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3698, .adv_w = 230, .box_w = 11, .box_h = 14, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 3775, .adv_w = 230, .box_w = 13, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 3866, .adv_w = 230, .box_w = 14, .box_h = 14, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 3964, .adv_w = 230, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4048, .adv_w = 230, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4132, .adv_w = 230, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4216, .adv_w = 230, .box_w = 8, .box_h = 20, .ofs_x = 3, .ofs_y = -4}, + {.bitmap_index = 4296, .adv_w = 230, .box_w = 11, .box_h = 21, .ofs_x = 2, .ofs_y = -4}, + {.bitmap_index = 4412, .adv_w = 230, .box_w = 7, .box_h = 20, .ofs_x = 4, .ofs_y = -4}, + {.bitmap_index = 4482, .adv_w = 230, .box_w = 10, .box_h = 8, .ofs_x = 2, .ofs_y = 6}, + {.bitmap_index = 4522, .adv_w = 230, .box_w = 14, .box_h = 2, .ofs_x = 0, .ofs_y = -5}, + {.bitmap_index = 4536, .adv_w = 230, .box_w = 7, .box_h = 5, .ofs_x = 3, .ofs_y = 12}, + {.bitmap_index = 4554, .adv_w = 230, .box_w = 11, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4615, .adv_w = 230, .box_w = 11, .box_h = 15, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 4698, .adv_w = 230, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4764, .adv_w = 230, .box_w = 12, .box_h = 15, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4854, .adv_w = 230, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 4920, .adv_w = 230, .box_w = 12, .box_h = 15, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 5010, .adv_w = 230, .box_w = 12, .box_h = 16, .ofs_x = 1, .ofs_y = -5}, + {.bitmap_index = 5106, .adv_w = 230, .box_w = 11, .box_h = 15, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 5189, .adv_w = 230, .box_w = 11, .box_h = 15, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 5272, .adv_w = 230, .box_w = 9, .box_h = 20, .ofs_x = 2, .ofs_y = -5}, + {.bitmap_index = 5362, .adv_w = 230, .box_w = 11, .box_h = 15, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 5445, .adv_w = 230, .box_w = 11, .box_h = 15, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 5528, .adv_w = 230, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 5594, .adv_w = 230, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 5655, .adv_w = 230, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 5721, .adv_w = 230, .box_w = 11, .box_h = 16, .ofs_x = 2, .ofs_y = -5}, + {.bitmap_index = 5809, .adv_w = 230, .box_w = 12, .box_h = 16, .ofs_x = 1, .ofs_y = -5}, + {.bitmap_index = 5905, .adv_w = 230, .box_w = 10, .box_h = 11, .ofs_x = 3, .ofs_y = 0}, + {.bitmap_index = 5960, .adv_w = 230, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 6021, .adv_w = 230, .box_w = 12, .box_h = 14, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 6105, .adv_w = 230, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 6166, .adv_w = 230, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 6232, .adv_w = 230, .box_w = 14, .box_h = 11, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 6309, .adv_w = 230, .box_w = 12, .box_h = 11, .ofs_x = 1, .ofs_y = 0}, + {.bitmap_index = 6375, .adv_w = 230, .box_w = 12, .box_h = 16, .ofs_x = 1, .ofs_y = -5}, + {.bitmap_index = 6471, .adv_w = 230, .box_w = 11, .box_h = 11, .ofs_x = 2, .ofs_y = 0}, + {.bitmap_index = 6532, .adv_w = 230, .box_w = 10, .box_h = 20, .ofs_x = 2, .ofs_y = -4}, + {.bitmap_index = 6632, .adv_w = 230, .box_w = 3, .box_h = 21, .ofs_x = 6, .ofs_y = -4}, + {.bitmap_index = 6664, .adv_w = 230, .box_w = 11, .box_h = 20, .ofs_x = 2, .ofs_y = -4}, + {.bitmap_index = 6774, .adv_w = 230, .box_w = 12, .box_h = 4, .ofs_x = 1, .ofs_y = 5}, + {.bitmap_index = 6798, .adv_w = 230, .box_w = 8, .box_h = 7, .ofs_x = 2, .ofs_y = 8}, + {.bitmap_index = 6826, .adv_w = 230, .box_w = 6, .box_h = 6, .ofs_x = 4, .ofs_y = 4}, + {.bitmap_index = 6844, .adv_w = 240, .box_w = 15, .box_h = 24, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 7024, .adv_w = 384, .box_w = 24, .box_h = 25, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 7324, .adv_w = 384, .box_w = 24, .box_h = 22, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 7588, .adv_w = 384, .box_w = 24, .box_h = 22, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 7852, .adv_w = 384, .box_w = 22, .box_h = 16, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 8028, .adv_w = 240, .box_w = 15, .box_h = 16, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 8148, .adv_w = 384, .box_w = 23, .box_h = 24, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 8424, .adv_w = 384, .box_w = 24, .box_h = 24, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 8712, .adv_w = 432, .box_w = 28, .box_h = 25, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 9062, .adv_w = 384, .box_w = 24, .box_h = 24, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 9350, .adv_w = 384, .box_w = 24, .box_h = 22, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 9614, .adv_w = 384, .box_w = 24, .box_h = 23, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 9890, .adv_w = 240, .box_w = 15, .box_h = 22, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 10055, .adv_w = 336, .box_w = 21, .box_h = 22, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 10286, .adv_w = 480, .box_w = 30, .box_h = 24, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 10646, .adv_w = 384, .box_w = 24, .box_h = 22, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 10910, .adv_w = 288, .box_w = 18, .box_h = 24, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 11126, .adv_w = 240, .box_w = 15, .box_h = 20, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 11276, .adv_w = 288, .box_w = 18, .box_h = 22, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 11474, .adv_w = 240, .box_w = 15, .box_h = 18, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 11609, .adv_w = 288, .box_w = 18, .box_h = 18, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 11771, .adv_w = 240, .box_w = 15, .box_h = 20, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 11921, .adv_w = 336, .box_w = 23, .box_h = 22, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 12174, .adv_w = 288, .box_w = 13, .box_h = 22, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 12317, .adv_w = 288, .box_w = 13, .box_h = 22, .ofs_x = 4, .ofs_y = -2}, + {.bitmap_index = 12460, .adv_w = 336, .box_w = 21, .box_h = 20, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 12670, .adv_w = 336, .box_w = 21, .box_h = 4, .ofs_x = 0, .ofs_y = 8}, + {.bitmap_index = 12712, .adv_w = 432, .box_w = 29, .box_h = 22, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 13031, .adv_w = 480, .box_w = 32, .box_h = 26, .ofs_x = -1, .ofs_y = -4}, + {.bitmap_index = 13447, .adv_w = 384, .box_w = 26, .box_h = 22, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 13733, .adv_w = 384, .box_w = 24, .box_h = 22, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 13997, .adv_w = 384, .box_w = 22, .box_h = 13, .ofs_x = 1, .ofs_y = 4}, + {.bitmap_index = 14140, .adv_w = 384, .box_w = 22, .box_h = 13, .ofs_x = 1, .ofs_y = 1}, + {.bitmap_index = 14283, .adv_w = 432, .box_w = 29, .box_h = 19, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 14559, .adv_w = 384, .box_w = 24, .box_h = 22, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 14823, .adv_w = 384, .box_w = 24, .box_h = 24, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 15111, .adv_w = 384, .box_w = 25, .box_h = 25, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 15424, .adv_w = 384, .box_w = 24, .box_h = 24, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 15712, .adv_w = 384, .box_w = 24, .box_h = 24, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 16000, .adv_w = 336, .box_w = 21, .box_h = 22, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 16231, .adv_w = 336, .box_w = 21, .box_h = 18, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 16420, .adv_w = 384, .box_w = 24, .box_h = 18, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 16636, .adv_w = 336, .box_w = 19, .box_h = 26, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 16883, .adv_w = 384, .box_w = 24, .box_h = 24, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 17171, .adv_w = 336, .box_w = 23, .box_h = 24, .ofs_x = -1, .ofs_y = -3}, + {.bitmap_index = 17447, .adv_w = 432, .box_w = 27, .box_h = 18, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 17690, .adv_w = 336, .box_w = 21, .box_h = 20, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 17900, .adv_w = 288, .box_w = 18, .box_h = 22, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18098, .adv_w = 480, .box_w = 30, .box_h = 22, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 18428, .adv_w = 432, .box_w = 27, .box_h = 16, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 18644, .adv_w = 432, .box_w = 27, .box_h = 16, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 18860, .adv_w = 432, .box_w = 27, .box_h = 16, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 19076, .adv_w = 432, .box_w = 27, .box_h = 16, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 19292, .adv_w = 432, .box_w = 27, .box_h = 16, .ofs_x = 0, .ofs_y = 1}, + {.bitmap_index = 19508, .adv_w = 480, .box_w = 31, .box_h = 20, .ofs_x = -1, .ofs_y = -1}, + {.bitmap_index = 19818, .adv_w = 336, .box_w = 19, .box_h = 26, .ofs_x = 1, .ofs_y = -4}, + {.bitmap_index = 20065, .adv_w = 336, .box_w = 21, .box_h = 24, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 20317, .adv_w = 384, .box_w = 25, .box_h = 25, .ofs_x = -1, .ofs_y = -4}, + {.bitmap_index = 20630, .adv_w = 384, .box_w = 24, .box_h = 24, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 20918, .adv_w = 432, .box_w = 27, .box_h = 18, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 21161, .adv_w = 288, .box_w = 18, .box_h = 24, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 21377, .adv_w = 384, .box_w = 24, .box_h = 16, .ofs_x = 0, .ofs_y = 1} +}; + +/*--------------------- + * CHARACTER MAPPING + *--------------------*/ + +static const uint16_t unicode_list_1[] = { + 0x0, 0x1f72, 0xe004, 0xef51, 0xef58, 0xef5b, 0xef5c, 0xef5d, + 0xef61, 0xef63, 0xef65, 0xef69, 0xef6c, 0xef71, 0xef76, 0xef77, + 0xef78, 0xef8e, 0xef93, 0xef98, 0xef9b, 0xef9c, 0xef9d, 0xefa1, + 0xefa2, 0xefa3, 0xefa4, 0xefb7, 0xefb8, 0xefbe, 0xefc0, 0xefc1, + 0xefc4, 0xefc7, 0xefc8, 0xefc9, 0xefcb, 0xefe3, 0xefe5, 0xf014, + 0xf015, 0xf017, 0xf019, 0xf030, 0xf037, 0xf03a, 0xf043, 0xf06c, + 0xf074, 0xf0a8, 0xf13b, 0xf190, 0xf191, 0xf192, 0xf193, 0xf194, + 0xf1d7, 0xf1e3, 0xf23d, 0xf254, 0xf2c9, 0xf4aa, 0xf712, 0xf7f2 +}; + +/*Collect the unicode lists and glyph_id offsets*/ +static const lv_font_fmt_txt_cmap_t cmaps[] = +{ + { + .range_start = 32, .range_length = 95, .glyph_id_start = 1, + .unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY + }, + { + .range_start = 176, .range_length = 63475, .glyph_id_start = 96, + .unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 64, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + } +}; + + + +/*-------------------- + * ALL CUSTOM DATA + *--------------------*/ + +#if LVGL_VERSION_MAJOR >= 8 +/*Store all the custom data of the font*/ +static lv_font_fmt_txt_glyph_cache_t cache; +static const lv_font_fmt_txt_dsc_t font_dsc = { +#else +static lv_font_fmt_txt_dsc_t font_dsc = { +#endif + .glyph_bitmap = glyph_bitmap, + .glyph_dsc = glyph_dsc, + .cmaps = cmaps, + .kern_dsc = NULL, + .kern_scale = 0, + .cmap_num = 2, + .bpp = 4, + .kern_classes = 0, + .bitmap_format = 0, +#if LVGL_VERSION_MAJOR >= 8 + .cache = &cache +#endif +}; + + +/*----------------- + * PUBLIC FONT + *----------------*/ + +/*Initialize a public general font descriptor*/ +#if LVGL_VERSION_MAJOR >= 8 +const lv_font_t lv_font_courierprimecode_24 = { +#else +lv_font_t lv_font_courierprimecode_24 = { +#endif + .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ + .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ + .line_height = 27, /*The maximum line height required by the font*/ + .base_line = 5, /*Baseline measured from the bottom of the line*/ +#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) + .subpx = LV_FONT_SUBPX_NONE, +#endif +#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 + .underline_position = -2, + .underline_thickness = 2, +#endif + .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ +}; + + + +#endif /*#if LV_FONT_COURIERPRIMECODE_24*/ + diff --git a/src/ui/c/ui.c b/src/ui/c/ui.c new file mode 100644 index 0000000..6a16792 --- /dev/null +++ b/src/ui/c/ui.c @@ -0,0 +1,327 @@ +#define _DEFAULT_SOURCE /* needed for usleep() */ + +#include "lvgl/lvgl.h" + +#include "ui.h" + +#include +#include + +lv_disp_t* drv_init(void); + +static lv_style_t style_title; +static lv_style_t style_text_muted; +static lv_style_t style_btn_red; +static const lv_font_t* font_large; +static lv_obj_t* virt_keyboard; +static lv_obj_t* tabview; /* main tabs content parent; lv_tabview_create */ + +static void textarea_event_cb(lv_event_t* e) +{ + lv_obj_t* textarea = lv_event_get_target(e); + lv_event_code_t code = lv_event_get_code(e); + if (code == LV_EVENT_FOCUSED) { + if (lv_indev_get_type(lv_indev_get_act()) != LV_INDEV_TYPE_KEYPAD) { + lv_keyboard_set_textarea(virt_keyboard, textarea); + lv_obj_set_style_max_height(virt_keyboard, NM_DISP_HOR * 2 / 3, 0); + lv_obj_update_layout(tabview); /* make sure sizes are recalculated */ + lv_obj_set_height(tabview, NM_DISP_VER - lv_obj_get_height(virt_keyboard)); + lv_obj_clear_flag(virt_keyboard, LV_OBJ_FLAG_HIDDEN); + lv_obj_scroll_to_view_recursive(textarea, LV_ANIM_OFF); + } + } else if (code == LV_EVENT_DEFOCUSED) { + lv_keyboard_set_textarea(virt_keyboard, NULL); + lv_obj_set_height(tabview, NM_DISP_VER); + lv_obj_add_flag(virt_keyboard, LV_OBJ_FLAG_HIDDEN); + lv_indev_reset(NULL, textarea); + } else if (code == LV_EVENT_READY || code == LV_EVENT_CANCEL) { + lv_obj_set_height(tabview, NM_DISP_VER); + lv_obj_add_flag(virt_keyboard, LV_OBJ_FLAG_HIDDEN); + lv_obj_clear_state(textarea, LV_STATE_FOCUSED); + lv_indev_reset(NULL, textarea); /* forget the last clicked object to make it focusable again */ + } +} + +static void create_bitcoin_panel(lv_obj_t* parent) +{ + lv_obj_t* label = lv_label_create(parent); + lv_label_set_text_static(label, "bitcoin tab isn't designed yet\nfollow https://nakamochi.io"); + lv_obj_center(label); +} + +static void create_lnd_panel(lv_obj_t* parent) +{ + lv_obj_t* label = lv_label_create(parent); + lv_label_set_text_static(label, "lightning tab isn't designed yet\nfollow https://nakamochi.io"); + lv_obj_center(label); +} + +static struct { + lv_obj_t* wifi_spinner_obj; /* lv_spinner_create */ + lv_obj_t* wifi_status_obj; /* lv_label_create */ + lv_obj_t* wifi_connect_btn_obj; /* lv_btn_create */ + lv_obj_t* wifi_ssid_list_obj; /* lv_dropdown_create */ + lv_obj_t* wifi_pwd_obj; /* lv_textarea_create */ + lv_obj_t* power_halt_btn_obj; /* lv_btn_create */ +} settings; + +/** + * update the UI with network connection info, placing text into wifi_status_obj as is. + * wifi_list is optional; items must be delimited by '\n' if non-null. + * args are alloc-copied and owned by lvgl. + */ +extern void ui_update_network_status(const char *text, const char *wifi_list) +{ + if (wifi_list) { + lv_dropdown_set_options(settings.wifi_ssid_list_obj, wifi_list); + } + lv_obj_clear_state(settings.wifi_connect_btn_obj, LV_STATE_DISABLED); + lv_obj_add_flag(settings.wifi_spinner_obj, LV_OBJ_FLAG_HIDDEN); + lv_label_set_text(settings.wifi_status_obj, text); +} + +static void wifi_connect_btn_callback(lv_event_t* e) +{ + (void)e; /* unused */ + lv_obj_add_state(settings.wifi_connect_btn_obj, LV_STATE_DISABLED); + lv_obj_clear_flag(settings.wifi_spinner_obj, LV_OBJ_FLAG_HIDDEN); + lv_label_set_text(settings.wifi_status_obj, "connecting ..."); + + char buf[100]; + lv_dropdown_get_selected_str(settings.wifi_ssid_list_obj, buf, sizeof(buf)); + nm_wifi_start_connect(buf, lv_textarea_get_text(settings.wifi_pwd_obj)); +} + +static void power_halt_btn_callback(lv_event_t *e) +{ + if (e->user_data) { /* ptr to msgbox */ + lv_obj_t *msgbox = e->user_data; + /* first button is "proceed", do shutdown */ + if (lv_msgbox_get_active_btn(msgbox) == 0) { + /* shutdown confirmed */ + nm_sys_shutdown(); + } + /* shutdown aborted or passthrough from confirmed shutdown. + * in the latter case, ui is still running for a brief moment, + * until ngui terminates. */ + lv_msgbox_close(msgbox); + return; + } + + /* first button must always be a "proceed", do shutdown; + * text is irrelevant */ + static const char *btns[] = {"PROCEED", "ABORT", NULL}; + lv_obj_t *msgbox = lv_msgbox_create( + NULL /* modal */, + "SHUTDOWN", /* title */ + "are you sure?", /* text */ + btns, + false /* close btn */); + lv_obj_center(msgbox); + lv_obj_add_event_cb(msgbox, power_halt_btn_callback, LV_EVENT_VALUE_CHANGED, msgbox); + return; +} + +static void create_settings_panel(lv_obj_t* parent) +{ + /******************** + * wifi panel + ********************/ + lv_obj_t* wifi_panel = lv_obj_create(parent); + lv_obj_set_height(wifi_panel, LV_SIZE_CONTENT); + lv_obj_t * wifi_panel_title = lv_label_create(wifi_panel); + lv_label_set_text_static(wifi_panel_title, LV_SYMBOL_WIFI " WIFI"); + lv_obj_add_style(wifi_panel_title, &style_title, 0); + + lv_obj_t* wifi_spinner = lv_spinner_create(wifi_panel, 1000 /* speed */, 60 /* arc in deg */); + settings.wifi_spinner_obj = wifi_spinner; + lv_obj_add_flag(wifi_spinner, LV_OBJ_FLAG_HIDDEN); + lv_obj_set_size(wifi_spinner, 20, 20); + lv_obj_set_style_arc_width(wifi_spinner, 4, LV_PART_INDICATOR); + + lv_obj_t* wifi_status = lv_label_create(wifi_panel); + settings.wifi_status_obj = wifi_status; + lv_label_set_text_static(wifi_status, "unknown status"); + lv_label_set_long_mode(wifi_status, LV_LABEL_LONG_WRAP); + lv_obj_set_height(wifi_status, LV_SIZE_CONTENT); + lv_label_set_recolor(wifi_status, true); + + lv_obj_t* wifi_ssid_label = lv_label_create(wifi_panel); + lv_label_set_text_static(wifi_ssid_label, "network name"); + lv_obj_add_style(wifi_ssid_label, &style_text_muted, 0); + lv_obj_t* wifi_ssid = lv_dropdown_create(wifi_panel); + settings.wifi_ssid_list_obj = wifi_ssid; + lv_dropdown_clear_options(wifi_ssid); + + lv_obj_t* wifi_pwd_label = lv_label_create(wifi_panel); + lv_label_set_text_static(wifi_pwd_label, "password"); + lv_obj_add_style(wifi_pwd_label, &style_text_muted, 0); + lv_obj_t* wifi_pwd = lv_textarea_create(wifi_panel); + settings.wifi_pwd_obj = wifi_pwd; + lv_textarea_set_one_line(wifi_pwd, true); + lv_textarea_set_password_mode(wifi_pwd, true); + lv_obj_add_event_cb(wifi_pwd, textarea_event_cb, LV_EVENT_ALL, NULL); + + lv_obj_t* wifi_connect_btn = lv_btn_create(wifi_panel); + settings.wifi_connect_btn_obj = wifi_connect_btn; + lv_obj_set_height(wifi_connect_btn, LV_SIZE_CONTENT); + lv_obj_add_event_cb(wifi_connect_btn, wifi_connect_btn_callback, LV_EVENT_CLICKED, NULL); + lv_obj_t* wifi_connect_btn_label = lv_label_create(wifi_connect_btn); + lv_label_set_text_static(wifi_connect_btn_label, "CONNECT"); + lv_obj_center(wifi_connect_btn_label); + + /******************** + * power panel + ********************/ + lv_obj_t* power_panel = lv_obj_create(parent); + lv_obj_set_height(power_panel, LV_SIZE_CONTENT); + lv_obj_t * power_panel_title = lv_label_create(power_panel); + lv_label_set_text_static(power_panel_title, LV_SYMBOL_POWER " POWER"); + lv_obj_add_style(power_panel_title, &style_title, 0); + + lv_obj_t* poweroff_text = lv_label_create(power_panel); + lv_label_set_text_static(poweroff_text, "once shut down, the power cord\ncan be removed."); + lv_label_set_long_mode(poweroff_text, LV_LABEL_LONG_WRAP); + lv_obj_set_height(poweroff_text, LV_SIZE_CONTENT); + lv_label_set_recolor(poweroff_text, true); + + lv_obj_t* power_halt_btn = lv_btn_create(power_panel); + settings.power_halt_btn_obj = power_halt_btn; + lv_obj_set_height(power_halt_btn, LV_SIZE_CONTENT); + lv_obj_add_style(power_halt_btn, &style_btn_red, 0); + lv_obj_add_event_cb(power_halt_btn, power_halt_btn_callback, LV_EVENT_CLICKED, NULL); + lv_obj_t* power_halt_btn_label = lv_label_create(power_halt_btn); + lv_label_set_text_static(power_halt_btn_label, "SHUTDOWN"); + lv_obj_center(power_halt_btn_label); + + /******************** + * layout + ********************/ + static lv_coord_t parent_grid_cols[] = {LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; + static lv_coord_t parent_grid_rows[] = { + LV_GRID_CONTENT, /* wifi panel */ + LV_GRID_CONTENT, /* power panel */ + LV_GRID_TEMPLATE_LAST + }; + lv_obj_set_grid_dsc_array(parent, parent_grid_cols, parent_grid_rows); + lv_obj_set_grid_cell(wifi_panel, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_set_grid_cell(power_panel, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 1, 1); + + static lv_coord_t wifi_grid_cols[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; + static lv_coord_t wifi_grid_rows[] = { + LV_GRID_CONTENT, /* title */ + 5, /* separator */ + LV_GRID_CONTENT, /* wifi status text */ + 30, /* wifi selector */ + 5, /* separator */ + LV_GRID_CONTENT, /* password label */ + 30, /* password input */ + 5, /* separator */ + LV_GRID_CONTENT, /* connect btn */ + LV_GRID_TEMPLATE_LAST + }; + lv_obj_set_grid_dsc_array(wifi_panel, wifi_grid_cols, wifi_grid_rows); + lv_obj_set_grid_cell(wifi_panel_title, LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 0, 1); + lv_obj_set_grid_cell(wifi_spinner, LV_GRID_ALIGN_END, 1, 1, LV_GRID_ALIGN_CENTER, 0, 1); + /* column 0 */ + lv_obj_set_grid_cell(wifi_status, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_START, 2, 7); + /* column 1 */ + lv_obj_set_grid_cell(wifi_ssid_label, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 2, 1); + lv_obj_set_grid_cell(wifi_ssid, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 3, 1); + lv_obj_set_grid_cell(wifi_pwd_label, LV_GRID_ALIGN_START, 1, 1, LV_GRID_ALIGN_START, 5, 1); + lv_obj_set_grid_cell(wifi_pwd, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 6, 1); + lv_obj_set_grid_cell(wifi_connect_btn, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 8, 1); + + static lv_coord_t power_grid_cols[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST}; + static lv_coord_t power_grid_rows[] = { + LV_GRID_CONTENT, /* title */ + 5, /* separator */ + LV_GRID_CONTENT, /* power off text and btn*/ + LV_GRID_TEMPLATE_LAST + }; + lv_obj_set_grid_dsc_array(power_panel, power_grid_cols, power_grid_rows); + lv_obj_set_grid_cell(power_panel_title, LV_GRID_ALIGN_STRETCH, 0, 2, LV_GRID_ALIGN_CENTER, 0, 1); + /* column 0 */ + lv_obj_set_grid_cell(poweroff_text, LV_GRID_ALIGN_START, 0, 1, LV_GRID_ALIGN_START, 2, 1); + /* column 1 */ + lv_obj_set_grid_cell(power_halt_btn, LV_GRID_ALIGN_STRETCH, 1, 1, LV_GRID_ALIGN_CENTER, 2, 1); +} + +static void tab_changed_event_cb(lv_event_t* e) +{ + (void)e; /* unused */ + uint16_t n = lv_tabview_get_tab_act(tabview); + switch (n) { + case 2: + nm_tab_settings_active(); + break; + default: + LV_LOG_INFO("unhandled tab index %i", n); + } +} + +extern int ui_init() +{ + lv_init(); + lv_disp_t* disp = drv_init(); + if (disp == NULL) { + return -1; + } + /* default theme is static */ + lv_theme_t* theme = lv_theme_default_init( + disp, + lv_palette_main(LV_PALETTE_BLUE), /* primary */ + lv_palette_main(LV_PALETTE_RED), /* secondary */ + true /*LV_THEME_DEFAULT_DARK*/, + LV_FONT_DEFAULT); + lv_disp_set_theme(disp, theme); + + font_large = &lv_font_courierprimecode_24; /* static */ + lv_style_init(&style_title); + lv_style_set_text_font(&style_title, font_large); + + lv_style_init(&style_text_muted); + lv_style_set_text_opa(&style_text_muted, LV_OPA_50); + + lv_style_init(&style_btn_red); + lv_style_set_bg_color(&style_btn_red, lv_palette_main(LV_PALETTE_RED)); + + /* global virtual keyboard */ + virt_keyboard = lv_keyboard_create(lv_scr_act()); + if (virt_keyboard == NULL) { + /* TODO: or continue without keyboard? */ + return -1; + } + lv_obj_add_flag(virt_keyboard, LV_OBJ_FLAG_HIDDEN); + + const lv_coord_t tabh = 60; + tabview = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, tabh); + if (tabview == NULL) { + return -1; + } + + /** + * tab_changed_event_cb relies on the specific tab order, 0-based index: + * 0: bitcoin + * 1: lightning + * 2: settings + */ + lv_obj_t* tab_btc = lv_tabview_add_tab(tabview, NM_SYMBOL_BITCOIN " BITCOIN"); + if (tab_btc == NULL) { + return -1; + } + create_bitcoin_panel(tab_btc); + lv_obj_t* tab_lnd = lv_tabview_add_tab(tabview, NM_SYMBOL_BOLT " LIGHTNING"); + if (tab_lnd == NULL) { + return -1; + } + create_lnd_panel(tab_lnd); + lv_obj_t* tab_settings = lv_tabview_add_tab(tabview, LV_SYMBOL_SETTINGS " SETTINGS"); + if (tab_settings == NULL) { + return -1; + } + create_settings_panel(tab_settings); + + lv_obj_add_event_cb(tabview, tab_changed_event_cb, LV_EVENT_VALUE_CHANGED, NULL); + return 0; +} diff --git a/src/ui/c/ui.h b/src/ui/c/ui.h new file mode 100644 index 0000000..c63d415 --- /dev/null +++ b/src/ui/c/ui.h @@ -0,0 +1,28 @@ +#ifndef NM_UI_H +#define NM_UI_H + +#include + +/** + * returns elapsed time since program start, in ms. + * rolls over when overflow occurs. + */ +uint32_t nm_get_curr_tick(); + +/** + * initiates system shutdown leading to poweroff. + */ +void nm_sys_shutdown(); + +/** + * invoken when the UI is switched to the network settings tab. + */ +void nm_tab_settings_active(); + +/** + * initiate connection to a wifi network with the given SSID and a password. + * connection, if successful, is persisted in wpa_supplicant config. + */ +int nm_wifi_start_connect(const char* ssid, const char* password); + +#endif diff --git a/src/ui/symbol.zig b/src/ui/symbol.zig new file mode 100644 index 0000000..0dcd0ce --- /dev/null +++ b/src/ui/symbol.zig @@ -0,0 +1,3 @@ +///! see lv_symbols_def.h +pub const Warning = &[_]u8{ 0xef, 0x81, 0xb1 }; +pub const Ok = &[_]u8{ 0xef, 0x80, 0x8c };